我在一个项目上工作了一段时间,试图找出我做错了什么,当我最终将“错误”缩小到以下代码无法按我预期工作的事实时:
function Alpha()
{
this.onion = 'onion';
function Beta()
{
alert(this.onion);
}
Beta();
}
alpha1 = new Alpha();
// Alerts 'undefined'
但是,如果我将代码更改为:
function Alpha()
{
var self = this;
this.onion = 'onion';
function Beta()
{
alert(self.onion);
}
Beta();
}
alpha1 = new Alpha();
// Alerts 'onion'
它的工作方式与我预期的一样。在浪费了我生命的大部分时间之后,谁能解释为什么它会这样工作?
最佳答案
这样工作是因为每个函数都关联了自己的执行上下文。
但是还有其他方法可以做到,例如:
function Alpha() {
this.onion = 'onion';
function Beta() {
alert(this.onion);
}
Beta.call(this);
}
var alpha1 = new Alpha();
// Alerts 'onion'
新的 ECMAScript 第 5 版标准引入了一种方法来持久化函数context,Function.prototype.bind
方法:
function Alpha() {
this.onion = 'onion';
var Beta = function () {
alert(this.onion);
}.bind(this);
Beta();
}
var alpha1 = new Alpha();
// Alerts 'onion'
我们可以说Beta
函数是绑定(bind) 的,无论您如何调用它,它的this
值都是完整的。
这个方法还没有被广泛支持,目前只有IE9pre3包含,但是你可以包含an implementation让它现在工作。
现在让我详细说明this
是如何工作的:
this
值存在于每个 execution context 上,并且对于函数代码是在进行函数调用时隐式设置的,其值取决于引用的形成方式。
在您的示例中,当您调用 Beta();
时,由于它未绑定(bind)到任何对象,我们可以说引用没有基对象,然后, this
值将引用全局对象。
当您调用绑定(bind)为对象属性的函数时会发生其他情况,例如:
var obj = {
foo: function () { return this === obj;}
};
obj.foo(); // true
如您所见,被调用的引用 obj.bar();
包含一个基础对象,即 obj
,以及 this
被调用函数中的值将引用它。
注意:reference type是一个抽象概念,为语言实现目的而定义,您可以在规范中查看详细信息。
this
值被隐式设置的第三种情况是当您使用 new
运算符时,它将引用一个新创建的对象,该对象继承自其构造函数的原型(prototype):
function Foo () {
return this; // `this` is implicitly returned when a function is called
} // with `new`, this line is included only to make it obvious
var foo = new Foo();
foo instanceof Foo; // true
Foo.prototype.isPrototypeOf(foo); // true
关于javascript - 如果没有 hack,就不能在私有(private) JavaScript 函数中访问“this”对象吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3274387/