
任何足够先进的技术都和魔法无异
var obj = {
id: "awesome",
cool: function coolFn() {
console.log(this.id);
},
};
var id = "not awesome";
obj.cool();
setTimeout(obj.cool, 100); // not awesome我们可以看到,我们预期这里会输出awesome,结果打印结果显示我们丢失了this的绑定,解决这个问题的办法有很多种,最常见的就是 var self = this
var obj = {
count: 0,
cool: function coolFn() {
var self = this;
if (self.count < 1) {
setTimeout(function timer() {
self.count++;
console.log("awesome?");
}, 100);
}
},
};
obj.cool(); // awesome用var self = this这种解决方案可以圆满解决理解和正确使用this绑定的问题,并且没有把问题复杂化,它使用的是我们常见的工具:词法作用域
this只是一个可以通过词法作用域和闭包进行引用的标识符,不关心this绑定的过程发生了什么
人们不喜欢写冗长的东西,尤其是一遍一遍地写。因此ES6的一个初衷就是帮助人们减少重复的场景,事实上包括修复某些习惯用法的问题,this就是其中一个。
ES6中的箭头函数引入了一个叫作this词法的行为:
var obj = {
count: 0,
cool: function coolFn() {
if(this.count < 1) {
setTimeout(() => {
this.count++;
console.log('awesome');
}, 100);
}
}
}简单来说,箭头函数在涉及this绑定时的行为和普通函数的行为完全不一样,它完全摒弃了所有普通 this的绑定规则,取而代之的是用当前的词法作用域覆盖了this本来的值。
因此,这个代码片段中的箭头函数并非是以某种不可预测的方式同所属的this进行了解绑定,而只是继承了 cool 函数的 this绑定(因此调用它不会出错)
除了可以少写点代码,箭头函数将程序员们经常犯的一个错误给标准化了,也就是混淆了this绑定规则和词法作用域规则。
this风格的代码模式呢?把它和词法作用域结合在一起非常让人头疼。在代码中使用两种风格的其中一种是非常自然的事情,但是不要将两种风格混在一起使用var obj = {
count: 0,
cool: function coolFn() {
if(this.count < 1) {
setTimeout(function timer() {
this.count++;
console.log('more awesome');
}.bind(this), 100);
}
}
}