在《你不知道的 JS》中对 this 有详细的讲解。关于回调函数中 this 使用,我有了这样的理解。
Talk is cheap, show me code.
var fn = function(callback) {
var value = 1;
return callback();
}
var value = 0;
var foo = {
value: 2,
bar: function() {
return this.value;
}
}
console.log(fn(foo.bar));
在非严格模式下,上述代码打印的结果是 0,即回调函数在执行时会导致 this 指向发生变化。
什么原因呢?
在《你不知道的 JS》书中有讲到:
var foo = {
bar: function () {
// this
}
}
var fn = foo.bar
这样赋值操作会导致隐式绑定的 this 指向发生变化。
而回调函数往往作为一个函数的参数被传入,而函数的参数传递是一个赋值过程。所以会导致隐式绑定 this 指向的问题。
由于 this 有四种绑定:直接绑定、隐式绑定、显示绑定、以及 new 绑定,它们的优先级依次递增。而像上面的赋值过程只会影响直接绑定和隐式绑定。
var fn = function(callback) {
var value = 1;
return callback.call(foo); // 这里 callback 被显示绑定
}
var value = 0;
var foo = {
value: 2,
bar: function() {
return this.value;
}
}
console.log(fn(foo.bar)); // 2,能得到我们想要的结果
故对于回调函数来说,在其内部使用 this 是不把稳的做法,解决方案可以在其调用时使用 call / apply / bind 显示绑定。