由于this值在箭头函数创建时确定的,所以会导致一些看似奇怪的行为。看下面代码,因为只有一个按钮,因此可以假设不需要构造函数。直接使用对象字面量。
<button id="testClick">Click Me!</button>
<script>
if (this === window) {
//全局代码中的this指向全局window对象
console.log('this === window');
}
var button = {
clicked: false,
//箭头函数是对象字面量的属性
click:() =>{
this.clicked = true;
//验证是否单击按钮
if (button.clicked) {
console.log('The button has been clicked');
}
//箭头函数中的this指向全局window对象
if (this === window) {
console.log('In arrow function this === window');
}
//Clicked属性存储在window对象上。
if (window.clicked) {
console.log('clicked is stored in window');
}
}
}
var elem = document.getElementById('testClick');
elem.addEventListener('click', button.click);
</script>
上述代码中发现button对象无法跟踪clicked的状态。
在全局代码中编写如下代码确认this的值。
if (this === window) {
//全局代码中的this指向全局window对象
console.log('this === window');
}
因此可以确定全局代码中的this指向全局window对象。
在全局代码中定义对象字面量,在字面量中定义箭头函数,那么箭头函数内的this执行全局window对象。
在button对象字面量中click属性是箭头函数:
var button = {
clicked: false,
//箭头函数是对象字面量的属性
click:() =>{
this.clicked = true;
//验证是否单击按钮
if (button.clicked) {
console.log('The button has been clicked');
}
//箭头函数中的this指向全局window对象
if (this === window) {
console.log('In arrow function this === window');
}
//Clicked属性存储在window对象上。
if (window.clicked) {
console.log('clicked is stored in window');
}
}
}
回顾一下规则:箭头函数在创建时确定了this的指向。由于click箭头函数是作为对象字面量的属性定义的,对象字面量在全局代码中定义,因此,箭头函数内部this值与全局代码的this值相同。
//箭头函数中的this指向全局window对象
if (this === window) {
console.log('In arrow function this === window');
}
可以看出全局代码的this指向全局window对象。因此,clicked属性被定义在全局window对象上,而不在button上。最后if判断可以确定clicked属性赋值在window对象上:
//Clicked属性存储在window对象上。
if (window.clicked) {
console.log('clicked is stored in window');
}
上述代码展示了箭头函数可能带来的副作用,会可能带来一些bug。
参考《JavaScript忍者秘籍》