我正在尝试将方法作为回调引用传递给另一个类的方法:
function A() {
this.callback = function(){return 0;};
}
A.prototype.set = function(cb) {
this.callback = cb;
};
A.prototype.test = function(){
console.log("test " + this.callback());
};
function B(o) {
this.prop = "blah B";
o.set(this.blah);
}
B.prototype.blah = function() {
console.log(this);
return this.prop;
};
我对执行的期望
a = new A();
b = new B(a);
a.test();
是结果
>B { prop="blah B", blah=function()}
>test blah B
但是控制台显示
>A { cb=function(), set=function(), test=function()}
>test undefined
好像方法blah
已分配给A
以执行..
为什么我得到这个结果?
我怎样才能得到我期望的结果?
答案 0 :(得分:3)
“好像方法blah已被分配给A执行”,你几乎得到它,只需在你的句子中用“a”替换“A”。实际上,默认情况下,this
指的是拥有该方法的实例。
碰巧,o.set(this.blah)
可以转换为a.callback = b.blah
,这意味着a.callback
和b.blah
现在引用相同的功能。换句话说,同一个函数现在由实例a
和b
所拥有:
a.callback() // "return (this -> a).prop" -> undefined
b.blah() // "return (this -> b).prop" -> "blah B"
粗略地说,您需要一种方法将this
“重定向”到b
内的callback
。
您可以使用closure:
var me = this;
o.set(function () {
// this -> a
// me -> b
return me.blah();
});
或bind(not supported by IE8 and below):
o.set(this.blah.bind(this));
答案 1 :(得分:2)
是的,这就是JavaScript的this
关键字的工作原理 - 它指的是当前的执行上下文,在这种情况下它是被调用的对象。您将其称为A
的方法。您需要将其称为B
实例上的方法。如果您不需要支持IE8或更低版本,则可以使用Function.prototype.bind绑定函数中的this
,使其始终指向B
实例。否则,A
实例需要引用要调用该方法的B
实例。
您可以使用var self = this;
黑客手动绑定该方法。您也可以在B
构造函数中执行此操作:
function B(o) {
var self = this;
this.prop = "blah B";
o.set(function() { self.blah(); });
}
但是,如果你可以对你正在尝试做的事情进行一些扩展,可能会有更优雅的解决方案。
答案 2 :(得分:2)
问题在于执行上下文 - JavaScript中函数的this
如何绑定。调用最后一行a.test()
时,callback
会在对象prop
的上下文中查找名为a
的属性。在您的情况下,对象a
没有prop
属性,因此undefined
。当您向prop
提供a
时,它可以正常工作。 console.log
here的最后小提琴。这里回调被调用两次,一次没有分配prop
,第二次分配相同:
function B(o) {
this.prop = "blah B";
o.set(this.blah);
o.prop = this.prop;
}
答案 3 :(得分:1)
在blah
方法中调用test
方法时,this
指向A
实例。由于A
没有prop
属性,因此返回undefined。
您需要将行o.set(this.blah);
更改为此o.set(this.blah.bind(this));
现在blah
始终绑定到B
的实例,并且当test
被调用this.prop
时,将返回"blah B"
这是预期的。