在对象中
看下面的一个例子,这里的 this 指向的是哪里呢?
const money = {
a: 1,
fn: () => {
console.log(this)
}
}
按照箭头函数定义的解释,谁实例化(或定义)就指向谁,那这里的 this 应该是对象 money。
事实却不是这样,执行上面结果如下:

arrow_this_obj.png
可以这样来理解,箭头函数不会创建自己的 this,它只会从自己的作用域链的上一层继承this。这里字面量的方式定义它封闭函数可以理解为就是 Window,所以这里箭头函数的 this 也指向 Window
另一种理解是箭头函数是用当前的词法作用域覆盖 this 本来的值,上面代码里词法作用域中 this 指向的是 Window
在方法中
function dollar() {
this.fn = () => {
console.log(this)
}
}
new dollar().fn() // this -> dollar
在类中
class Dollar {
fn = () => {
console.log(this)
}
}
new Dollar().fn() // this -> Dollar
class RMB {
constructor(fn) {
this.fn = fn
}
}
new RMB(new Dollar().fn).fn() // this -> Dollar
- 按照上面描述,this 继承自上一层,箭头函数定义在方法或类中指向的就是实例本身,不论方法在哪里执行、谁来执行。
普通函数中 this 的行为
this 指向执行这个方法的上下文(对象或类)
函数根据它是被如何调用的来定义这个函数的this值
首先看一个普通的例子
class abe {
fn() {
console.log(this)
}
}
class dd1 {
constructor(d) {
this.fn = d.fn
}
}
new abe().fn() // this -> abe
new abe().fn.call(new dd1({})) // this -> dd1
new dd1(new abe()).fn() // this -> dd1
从这个结果可以看出 this 指向执行时的上下文,即谁执行指向谁。
const aba = {
a: 1,
fn: function() {
console.log(this)
}
}
function abi() {
this.fn = function() {
console.log(this)
}
}
class abe {
fn() {
console.log(this)
}
}
分别在对象、方法、类中验证,普通函数定义的 this 指向都满足一致的规则,谁执行指向谁。
结论
- 普通函数中 this 指向执行这个方法的上下文(对象或类),谁执行指向谁
- 箭头函数中 this 继承自上一层的 this,谁实例化指向谁,没有实例的指向上一层(比如对象中定义的方法)
- 不论普通 function 还是 arrow function ,直接执行的 this 大多是指向当前定义的上下文
- 箭头函数的特点,语法简单、没有自己的 this、arguments、new、prototype
一个特殊的箭头函数
箭头函数不会创建自己的this,它只会从自己的作用域链的上一层继承this。
箭头函数没有定义this绑定。
function c() {
this.fn = () => {
console.log(this)
};
return this
}
new c().fn() // c
c().fn() // window
// 可以这样理解
// c() 没有执行上下文默认是 window,那箭头函数指向上一层也是 window
// new 的操作是创建一个空对象并将这个对象做为 this 的上下文
'use strict';
var obj = {
a: 10
};
Object.defineProperty(obj, "b", {
get: () => {
console.log(this.a, typeof this.a, this);
return this.a+10;
// 代表全局对象 'Window', 因此 'this.a' 返回 'undefined'
}
});
obj.b;
参照
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Functions/Arrow_functions