我们在面试中经常会被问到一些题目:"这里的 this.xxx
指的是什么?"
其实面试官并不是想要问你 this.xxx
而是想要问 this
指的是什么。
那么接下来我先简要介绍一下this
,再拿几道例题来聊聊常见的 this
指向问题。
简要介绍 this
this
是JavaScript中的一个关键字,它在函数被调用时自动定义。this
的值在函数调用时确定,并且在函数执行过程中不能更改。它引用的是调用函数的对象------由于JavaScript允许函数在多个上下文中使用,因此this
的具体值取决于函数的调用方式。
在JavaScript中,this
主要有以下几种使用情况:
- 全局作用域或函数外部 :在非严格模式下,
this
指向全局对象(在浏览器中,这通常是window
对象)。在严格模式下,this
是undefined。 - 普通函数调用 :当一个函数作为一个普通函数调用时(即不是作为对象的方法或者使用
new
关键字调用),this
通常指向全局对象。但是在严格模式下,它会是undefined。 - 作为对象的方法调用 :当一个函数作为对象的方法被调用时,
this
指向这个调用方法的对象。 - 使用new关键字调用 :当一个函数使用
new
关键字调用时,JavaScript会创建一个新的空对象,并将这个新对象的原型链接到构造函数的prototype对象,并将this
绑定到这个新对象上。 - 使用call、apply或bind方法 :JavaScript的函数对象提供了call、apply和bind方法,可以用来改变函数的执行上下文,即
this
的指向。 - 箭头函数 :箭头函数中的
this
是继承自外部的上下文,而不是在箭头函数被调用时创建的新的上下文。
来几道题
Q1
js
var name = 'Bob';
var a = {
name: 'Mary',
getName: () => {
console.log(this.name);
}
}
a.getName();
a.getName.call();
这里的答案是 Bob
和 Bob
,前者是因为箭头函数内的this
与外部的this
是一致的,所以这里的 this
直接相当于 window
,而后者是因为.call
的调用没法改变箭头函数。
Q2
js
var name = 'Bob';
var a = {
name: 'Mary',
getName: function() {
console.log(this.name);
}
}
a.getName();
a.getName.call();
这里的答案是 Mary
和 Bob
,第一个值直接适用于我们介绍this
的第三点 ==> 作为对象的方法调用,而第二个为什么会是Bob
呢,别急,我们一个一个来说,我们调用了.call
,那么我们可以看一下call
的简略实现
js
Function.prototype.call = function(context, ...args) {
context = context || window;
args = args ? args : [];
const key = Symbol();
context[key] = this;
const result = context[key](...args);
delete context[key];
return result;
}
从call
的简略实现我们可以知道,如果说我们什么都不调用,这里默认绑定的是 window
,所以第二个值是返回的 Bob
,现在你明白了莫。