JavaScript this 指向基础
上一篇文章 JavaScript 对象方法 初次接触了 this,知道对象方法里的 this 指向调用者。这一节把 this 的指向规则系统梳理一遍,这是 JavaScript 的难点,也是面试常客。
this 是函数体内的一个特殊关键字,它的值不是定义时决定的,而是由调用方式决定。同一个函数,用不同方式调用,this 指向就不同。先记住这个前提,后面的规则就容易理解了。
对象方法里的 this
对象方法被调用时,this 指向这个对象本身。谁调用,this 就是谁。
const cat = {
name: '咪咪',
speak: function () {
console.log(this.name);
},
};
cat.speak();
输出 咪咪。speak 由 cat 调用,this 就是 cat,所以 this.name 是 咪咪。
再看跨对象的例子。同一个函数放进两个对象,各自调用时 this 指向各自的对象。上一篇文章里的 tom 和 jerry 就是这种情况,可以回去再看一遍,两个输出互不干扰。
函数单独调用时的 this
函数不加任何对象直接调用,比如 show(),这时的 this 指向什么。在浏览器里,这种调用方式下 this 指向 window 全局对象,严格模式下是 undefined。
function show() {
console.log(this);
}
show();
浏览器里输出 window。show 前面没有对象,this 就落到了全局对象上。这种写法平时基本用不到,知道有这回事就行,写代码时不要在函数里依赖 this 去找全局。
箭头函数不绑定 this
箭头函数是 ES6 的写法,和普通函数最大的区别之一就在 this。普通函数有自己的 this,取决于调用方式。箭头函数不绑定自己的 this,它会继承外层函数的 this。
对比同一个对象里两种函数的差异。
const obj = {
name: '对象A',
normal: function () {
console.log(this.name);
},
arrow: () => {
console.log(this.name);
},
};
obj.normal();
obj.arrow();
第一行输出 对象A。normal 是普通函数,由 obj 调用,this 是 obj。第二行输出 undefined。arrow 是箭头函数,自己没有 this,往外层找,外层是全局环境,this 是 window,window 上没有 name,得到 undefined。
箭头函数在嵌套场景里最有用。普通函数嵌套时常常丢掉外层的 this,箭头函数不会,它会一直沿用外层 this。这个特性到 ES6 教程里会展开讲,现在先有个印象。
小结
this 是函数体内的特殊关键字,值由调用方式决定。对象方法调用时 this 指向该对象,谁调用指向谁。函数单独调用时,浏览器里 this 指向 window,严格模式下是 undefined。箭头函数不绑定自己的 this,继承外层函数的 this。call、apply、bind 这些手动指定 this 的工具,留到进阶阶段再学。