在我正确的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()工作?
此外,我想干净利落地做到这一点:即,不要在多个地方引用对象的名称。
答案 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);
apply
和call
之间的区别在于您将参数传递给被调用函数的方式: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);
}