持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第2天,点击查看活动详情
this 的指向一直是面试中频繁出现的考点之一,也是容易混淆的点。不仅包括对于 this 本身的考察,还有如何修改 this 指向,以及ES6 的箭头函数中 this 的特点等等的考察
关于 this
this 是 JavaScript 中的一个关键字,指的是函数运行时所在的环境。它的特点是:
- 只能在函数内部使用,并且永远指向最后一个调用它的对象
- this一旦被确定了,就不可以再更改,修改this运行后会报错
在不同的开发场景中,this 绑定的方式也有所不同,总体分为几种:
- 默认绑定
- 隐式绑定
- 显示绑定
- new绑定
默认绑定
先来看看下面这段代码,就是我们常见的默认绑定
var msg = 'haha';
function say() {
return this.msg;
}
console.log(say()); //msg
say()函数的调用位置为最后一行,也就是window,因此 this 的指向是 window
隐式绑定
隐式绑定时是当函数作为某个对象的方法调用时绑定, this 指向它上一级的对象
let obj = {
a:100,
b:{
c: 200,
fn:function(){
console.log(this.name); // 1.undefined
}
}
}
obj.b.fn(); // 调用函数fn()的对象是b
上面这段代码,1.处的值为 undefined ,指向它上一级的对象b,而 b 中没有a这个属性,所以是 undefined。
但是还有一个很容易踩坑的地方,我们来看这样一段代码:
let obj = {
a:100,
b:{
a: 200,
fn:function(){
console.log(this); //window
console.log(this.a); //undefined
}
}
}
let doSomething = obj.b.fn;
doSomething();
当对象中声明了函数,调用它的时候结果却指向了window,这是为什么呢?
其实就是上面提到的: this 永远指向最后一个调用它的对象。而最后一个调用它的对象不是b,而是doSomething,(fn赋值给而是doSomething的时候没有执行)。所以这里 this 的指向为window
new 关键词
使用new关键字生成的实例对象,this会指向这个实例对象。如果有返回值对象,则指向返回值
function fn()
{
this.msg = 'haha';
// return {}; 1. 如果有返回值对象,result.msg 会输出 undefined
// return null; 2. null的类型为对象,但此时依旧指向实例对象,result.msg 会输出 haha
}
let result = new fn();
console.log(result.msg); //haha
- return {}; 1.处 如果有返回值对象,result.msg 会输出 undefined
- return null; 2.处 null的类型为对象,但此时依旧指向实例对象,result.msg 会输出 haha
显式绑定
call() 、apply() 、bind() 都是用来改变函数运行时this指向的(也就是改变函数执行时的上下文),执行后会指向其传入的参数。
想要了解它们,首先需要了解 this 关键字。
优先级
上述的几种方式优先级:new > 显示绑定> 隐式绑定 > 默认绑定
那么当我们想要去改变 this 的指向时,该怎么做呢?
改变 this 的指向
- 使用
apply、call、bind - 使用 ES6 的箭头函数
- new 实例化一个对象
- 使用
_this = this