箭头函数中this的指向

这是coderwhy出的一道习题,我截取了习题中箭头函数的部分出来

var name = 'window'
var person1 = {
  name: 'person1',
  foo2: () => console.log(this.name),
  foo4: function () {
    return () => {
      console.log(this.name)
    }
  }
}
var person2 = { name: 'person2' }

person1.foo2.call(person2);
person1.foo4()();
person1.foo4.call(person2)();
person1.foo4().call(person2);
call的作用

可以认为call方法干了这么一件事

function Person(name) {
  // 执行Person.call(obj)时,在这里隐式地执行了一句var this = obj
  this.name = name
}
var obj = {}
Person.call(obj, 'cheng')

但是对箭头函数来说:箭头函数体中的this对象,是定义函数时的对象,而不是使用函数时的对象

所以person1.foo2.call(person2),它不可能在() => console.log(this.name)函数体里面隐式地执行一句var this = person2,因为这个箭头函数访问到的this是从外层作用域中取到的,它不可能声明var this在自己的作用域中,因而也不可能被赋值

所以person1.foo2.call(person2)会打印出window

分析person1.foo4()():注意它的执行上下文

foo4: function () {
  // person1.foo4()执行时,这里会隐式地生成var this = person1,这里还是普通函数的作用域
  return () => {
    console.log(this.name)
  }
}

理解了这一句之后,就能理解后三句话
person1.foo4()();
person1.foo4.call(person2)();
person1.foo4().call(person2);

打印出person1 person2 person1

定义在内部的函数(箭头函数)被保存到了外部,其实还用到了闭包的知识点

Babel编译

我们可以使用babel对题目中的代码做编译,然后观察,这样看到的更明显

"use strict";
var _this = void 0;
var name = 'window';
var person1 = {
  name: 'person1',
  foo2: function foo2() {
    return console.log(_this.name);
  },
  foo4: function foo4() {
    var _this2 = this;
    return function () {
      console.log(_this2.name);
    };
  }
};

一目了然

但是有一个小问题:严格模式下,局部的this在预编译时为undefine,但全局的this依然指向window,之前代码里的foo2: () => console.log(this.name),这里的this是全局的this,预编译时为window,这里直接搞成void 0了,有点粗暴

完整习题

https://mp.weixin.qq.com/s/hYm0JgBI25grNG_2sCRlTA

总结
  • 普通函数执行时的this对象:不要看外层作用域
  • 箭头函数执行时的this对象:一定要看外层作用域
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值