this在标准函数和箭头函数中有不同的行为。
在标准函数中,this 引用的是把函数当成方法调用的上下文对象,这时候通常称其为 this 值(在网页的全局上下文中调用函数时,this 指向 windows)
window.color = 'red';
let o = {
color: 'blue'
};
function sayColor() {
console.log(this.color);
}
sayColor(); // 'red'
o.sayColor = sayColor;
o.sayColor(); // 'blue'
- 定义在全局上下文中的函数 sayColor()引用了 this 对象。
- 这个 this 到底引用哪个对象必须到函数被调用时才能确定。
- 因此这个值在代码执行的过程中可能会变。
- 如果在全局上下文中调用sayColor(),这结果会输出”red”,因为 this 指向 window,而 this.color 相当于 window.color。
- 而在把 sayColor()赋值给 o 之后再调用 o.sayColor(),this 会指向 o,即 this.color 相当于o.color,所以会显示”blue”。
在箭头函数中,this引用的是定义箭头函数的上下文。
下面的例子演示了这一点。在对sayColor()的两次调用中,this 引用的都是 window 对象,因为这个箭头函数是在 window 上下文中定义的:
window.color = 'red';
let o = {
color: 'blue'
};
let sayColor = () => console.log(this.color);
sayColor(); // 'red'
o.sayColor = sayColor;
o.sayColor(); // 'red'
在事件回调或定时回调中调用某个函数时,this 值指向的并非想要的对象。
此时将回调函数写成箭头函数就可以解决问题。这是因为箭头函数中的 this 会保留定义该函数时的上下文:
function King() {
this.royaltyName = 'Henry';
// this 引用 King 的实例
setTimeout(() => console.log(this.royaltyName), 1000);
}
function Queen() {
this.royaltyName = 'Elizabeth';
// this 引用 window 对象
setTimeout(function() { console.log(this.royaltyName); }, 1000);
}
new King(); // Henry
new Queen(); // undefined
注意 函数名只是保存指针的变量。因此全局定义的 sayColor()函数和 o.sayColor() 是同一个函数,只不过执行的上下文不同。