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

Using bind to ensure method refers to object, but it doesn't seem to be working

本文关键字:引用 对象 不起作用 bind 确保 方法 使用      更新时间:2023-09-26

为了用正确的Javascript进行实验,我试图从另一个方法(WaitAndSayHello)运行一个方法。由于涉及回调,我使用了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",然后第二次以"Object#没有方法SayHello"失败。我可以从console.log中看到,"this"指的是该事件。然而,不应该使用bind()来解决这个问题吗?

如何使bind()工作?

此外,我想干净地做这件事:即,不在多个地方引用对象的名称。

您不能"延迟呼叫".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)

您应该使用:

this.WaitAndSayHello.call(this);

this.WaitAndSayHello.apply(this);

applycall之间的区别在于将参数传递给被调用函数的方式:假设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);
    }