使用bind来确保方法引用对象,但它似乎不起作用

时间:2012-02-15 11:15:54

标签: javascript oop methods bind

在我正确的Javascript中进行实验,我试图从另一个方法(WaitAndSayHello)运行一个方法(SayHello)。由于涉及回调,我使用bind来确保每个方法中的'this'引用该对象。

pretendThingConstructor = function (greeting) {
    this.greeting = greeting;

    this.SayHello = function() {
        console.log(this.greeting); // Works
    };

    this.WaitAndSayHello = function() {
        setTimeout(function() { 
            console.log(this)  
            this.SayHello() // Fails
        }, 500);
    }
    this.WaitAndSayHello.bind(this); // This bind() doesn't seem to work
}


var pretend_thing = new pretendThingConstructor('hello world');
pretend_thing.SayHello();
pretend_thing.WaitAndSayHello();

代码打印'hello world',然后第二次'对象#没有方法'SayHello'失败。我可以从console.log中看到'this'指的是事件。但是不应该使用bind()修复此问题吗?

如何使bind()工作?

此外,我想干净利落地做到这一点:即,不要在多个地方引用对象的名称。

2 个答案:

答案 0 :(得分:5)

你不能“迟到”.bind()。你需要在函数声明时调用它,比如

this.WaitAndSayHello = function() {
    setTimeout(function() { 
        console.log(this)  
        this.SayHello() // Fails
    }, 500);
}.bind(this)

此外,您传递到setTimeout()的匿名函数会创建一个新的上下文,因此具有自己的this上下文值。

您需要在

等变量中保留对“外this”的引用
this.WaitAndSayHello = function() {
    var self = this;

    setTimeout(function() { 
        console.log(self)  
        self.SayHello() // succeeds
    }, 500);
}.bind(this)

或再次使用.bind(),例如

this.WaitAndSayHello = function() {
    setTimeout(function() { 
        console.log(this)  
        this.SayHello() // succeeds
    }.bind(this), 500);
}.bind(this)

答案 1 :(得分:1)

你应该使用:

this.WaitAndSayHello.call(this);

this.WaitAndSayHello.apply(this);

applycall之间的区别在于您将参数传递给被调用函数的方式:imag WaitAndSayHello收到了一些参数:

this.WaitAndSayHello = function(toWho, helloMessage){
 ...
}

使用call,您可以在上下文之后传递参数,因为您正常调用函数:

this.WaitAndSayHello.call(this, 'Bob', 'Hello');

使用apply,您必须将args作为数组传递:

this.WaitAndSayHello.apply(this, ['Bob', 'Hello']);

修改

抱歉,我读错了你的代码,@ jAndy的anwser真的是正确的,但是,使用我的逻辑你可以做类似的事情:

this.WaitAndSayHello = function() {
        setTimeout.call(this, function() { 
            console.log(this)  
            this.SayHello() // Fails
        }, 500);
    }