将方法作为回调传递

时间:2013-12-12 05:59:25

标签: javascript oop callback

我正在尝试将方法作为回调引用传递给另一个类的方法:

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以执行..

为什么我得到这个结果?
我怎样才能得到我期望的结果?

4 个答案:

答案 0 :(得分:3)

“好像方法blah已被分配给A执行”,你几乎得到它,只需在你的句子中用“a”替换“A”。实际上,默认情况下,this指的是拥有该方法的实例

碰巧,o.set(this.blah)可以转换为a.callback = b.blah,这意味着a.callbackb.blah现在引用相同的功能。换句话说,同一个函数现在由实例ab所拥有:

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();
});

bindnot 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"这是预期的。