关于 Arrow Function 的 this

首先

箭头函数(Arrow Function)是 ECMAScript 6 中的新特性。

问题

从代码中分析箭头函数的指向问题:

function foo() {
    return ()=>{
        console.log(this.a)
       }
}

const obj1 = {a:1}
const obj2 = {a:2}

const bar = foo.call(obj1)
bar.call(obj2)

我们将会看到哪一个 obj 的 a 会被打印出呢?

假如 foo 函数 return 的不是箭头函数而是传统的function,结果又是如何?

function foo() {
    return function(){
        console.log(this.a)
       }
}

const obj1 = {a:1}
const obj2 = {a:2}

const bar = foo.call(obj1)
bar.call(obj2)

结果

箭头函数中,foo 外部函数首先绑定了 obj1,this 指向 obj1。由于箭头函数不更改 this 的指向, 所以内部函数 this 与外部函数的 this 一致。但内部函数再次绑定 obj2 使得 this 指向 obj2 了么? 并没有。因为箭头函数的 this 不是在运行的时候绑定的,而是在定义的时候绑定的, 指向词法作用域中的 this

tips:
词法作用域(lexical scoping)也叫静态作用域。
Javascript 采用的就是词法作用域。
因为采用词法作用域,函数的作用域在函数定义的时候就决定了。
采用静态作用域时,会从内向外寻找变量。
所以箭头函数寻找 this 会从内向外寻找。

var x=1;
var obj={
  x:2,
  print: () => { // 箭头函数使用词法作用域寻找 this。 从内向外寻找 this, 这里一直找到全局变量, 所以 this.x 指向外部 x
    console.log(this.x)
  }
}
obj.print();
var x=1;
var obj={
  x:2,
  print: function() { // 普通函数根据 ‘执行上下文’
    console.log(this.x)
  }
}
obj.print();
var a = 1
var obj = {
    a:2,
    b:{
        a:3,
        c: {
            a:4,
            getA: ()=> { // 仍然找到全局变量
                console.log(this.a)
            }
        }
    }
}

obj.b.c.getA()
var a = 1
var obj = {
    a:2,
    b:{
        a:3,
        c: {
            a:4,
            getA: function() { // 执行时的上下文 this = c
                // 箭头函数找到 this,也就是 c
                return () => console.log(this.a)
            }
        }
    }
}

obj.b.c.getA()()

所以,碰到箭头函数,我们根据词法作用域找 this,传统函数,我们根据执行上下文来判断 this 的指向。

再通俗一点, 传统函数,谁调用这个函数,this 就指向谁。(运行时确定)
而箭头函数的 this ,根据箭头函数定义的位置,从内向外查找到的第一个 this 就是它的 this。(定义时确定)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值