也许标题听起来有点奇怪(请改进它) - 但我需要一个针对以下场景的解决方案。我有以下代码:
var Foo = function () {
this._hello = "world!";
};
Foo.prototype.bar = function () {
console.log(this._hello);
};
var f = new Foo();
f.bar(); // => "world!"
f.bar.apply(this); // => undefined
我知道apply
会更改上下文,因此在bar
内部,this
将成为全局对象(在第二次调用时)。
但我需要的是从this
函数访问Foo
。我看到的解决方案是:
var Foo = function () {
var self = this;
self._hello = "world!";
self.bar = function () {
console.log(self._hello);
};
};
但是,我会选择不在另一个函数中使用方法声明。
我更喜欢定义相同列级别的方法(仅用于代码样式):
var Foo = ...;
Foo.prototype.method = ...;
这可能吗?怎么样?
答案 0 :(得分:2)
您可以使用bind()
method来解决these kinds of problems。而不是something.method(f.bar)
调用something.method(f.bar.bind(f))
来始终在预期的上下文(bar
)上调用f
方法。
如果您不希望在每个传递bind
的位置使用bar
作为回调,您也可以将它放在构造函数中,为每个实例创建一个专用的绑定函数。默认值:
function Foo() {
this._hello = "world!";
this.bar = this.bar.bind(this);
}
Foo.prototype.bar = function () {
console.log(this._hello);
};
var f = new Foo;
something.method(f.bar); // works!
答案 1 :(得分:0)
通过像这样为原型分配一个函数,不可能做到这一点。
除非您直接为f.bar
分配内容(如第二个示例和Bergi的答案),否则您将获得f.bar
的值是对您指定的函数的引用原型的属性Foo.prototype.bar
。对于以Foo.prototype
为原型的任何其他对象,这将是完全相同的函数对象。此函数对象中没有f
的引用。
因此,当您致电f.bar()
时,this
如何引用f
的值?它是一种特殊语法,基本上等同于f.bar.apply(f)
。只有您使用此方法调用语法才能将this
设置为f
的值。对f.bar
的任何其他引用只会评估原型的单个共享函数对象。
如果您使用f.bar.apply(somethingElse)
来呼叫,this
现在设置为somethingElse
,并且与f
的所有关联都将丢失。
这不是apply(...)
更改范围的问题。 fn.apply(x)
在this
内将x
设置为fn
,而y.fn()
将this
设置为y
。
同样,在您的示例中,如果您将f.bar
分配给变量,然后通过变量调用它而不是使用方法调用语法f.bar()
,那么您的this
将是{ {1}}对象(如果在浏览器中运行),您将再次获得window
。
undefined