深刻理解箭头函数的this指向问题!

最近在学习时翻阅了一系列关于箭头函数的详解,发现了两个关于箭头函数this指向容易弄错的关键点,本文主旨就是将其指出和加深对其的理解。

两个关键点

①箭头函数的this指向外层上下文

②箭头函数的this在定义时就绑定了

先来点基础的:

箭头函数与普通函数在处理`this`指向上有一个重要的区别。普通函数的`this`是在函数被调用时动态确定的,而箭头函数在定义时绑定了词法上下文中的`this`值,因此箭头函数的`this`指向是固定的,无法通过不同的调用方式来改变。

具体来说:

1. 箭头函数的`this`指向外层上下文: 箭头函数的`this`指向是在定义时确定的,并且取决于箭头函数所处的词法上下文。它会捕获包含它的最近一层非箭头函数上下文的`this`值,无论该函数被调用的位置如何,`this`指向都不会改变。

2. 普通函数的`this`动态绑定: 普通函数的`this`是在函数被调用时动态确定的,它取决于函数的调用方式。在不同的调用场景下,`this`可能指向不同的对象或者全局对象(浏览器环境下是`window`对象)。

这里再举一个例子来说明两者的区别:

const obj = {
  name: 'Alice',
  arrowFunc: () => {
    console.log("Arrow function:", this.name);
  },
  regularFunc: function() {
    console.log("Regular function:", this.name);
  },
};

const outerRegularFunc = obj.regularFunc;
const outerArrowFunc = obj.arrowFunc;

obj.regularFunc();     // Output: Regular function: Alice
obj.arrowFunc();       // Output: Arrow function: undefined

outerRegularFunc();    // Output: Regular function: undefined
outerArrowFunc();      // Output: Arrow function: undefined

在上面的例子中,`obj`对象包含了一个箭头函数`arrowFunc`和一个普通函数`regularFunc`。

当我们在`obj`对象上直接调用`regularFunc`时,`this`指向`obj`对象,输出为`Regular function: Alice`。但是当我们调用`arrowFunc`时,箭头函数的`this`指向并不是`obj`对象,而是外层(全局)的上下文,输出为`Arrow function: undefined`。

当我们将`regularFunc`和`arrowFunc`赋值给`outerRegularFunc`和`outerArrowFunc`变量,并在全局上下文中调用时,无论如何调用,箭头函数的`this`仍然指向外层的上下文,输出依然为`Arrow function: undefined`。普通函数在不同的调用方式下,`this`的指向可能会变化。

详解关键点:

箭头函数的this指向外层词法上下文

首先了解一个概念,词法上下文,简单来说就是一个自身和所处的环境的结合,可以理解为一块作用域,上述代码中的arrowFunc是一个箭头函数,它的词法上下文由包含它的对象 obj所处的词法上下文决定。obj的词法上下文是什么?显而易见,是全局对象window!因此此处箭头函数arrowFunc的this在定义时就绑定指向了全局对象window,如果是在严格模式下,则指向undefined。

好的,那么简单修改一下上面的例子:

const obj2 = {
    name: 'abc',
    arrowFunc: function () {
        const innerArrowFunc = () => {
            console.log("Arrow function:", this.name);
        };
        innerArrowFunc(); // 调用内部的箭头函数
    },
};
obj2.arrowFunc();// Arrow function: abc

在这个例子中,`arrowFunc`是一个普通函数,它的词法上下文由调用它的对象 `obj2` 决定。所以,当我们在 `obj2` 上调用 `arrowFunc` 时,`this` 指向的是 `obj2` 对象。

然后,在 `arrowFunc` 内部定义了一个箭头函数 `innerArrowFunc`。箭头函数的词法上下文由包含它的最近的非箭头函数上下文决定,即 `arrowFunc` 函数的词法上下文。因此,`innerArrowFunc` 的词法上下文与 `arrowFunc` 是相同的,它们共享相同的 `this` 值。

所以,当我们调用 `innerArrowFunc()` 时,箭头函数 `innerArrowFunc` 的 `this` 指向与外层的普通函数 `arrowFunc` 的 `this` 指向是一样的,都指向 `obj2` 对象。

因此,在我们调用obj2.arrowFunc()时,打印的结果为 ‘Arrow function: abc’。

总结,要注意理解什么叫包含箭头函数的外层词法上下文指向的this!

箭头函数的this在定义时绑定

还是上面的obj2的案例,我问一个问题,如果我去掉后面的调用,像这样:

const obj2 = {
    name: 'abc',
    arrowFunc: function () {
        const innerArrowFunc = () => {
            console.log("Arrow function:", this.name);
        };
        innerArrowFunc(); // 调用内部的箭头函数
    },
};

像这样的情况,箭头函数定义了吗?或者说我调打印:console.log(obj2.name) 箭头函数定义了吗?

答案是没有,显而易见,箭头函数的定义被包裹在了一个函数内部,这个函数只有在被调用时,才会去定义一个箭头函数。因此此时,箭头函数没有被定义,那么它的this指向也就没有绑定!深刻理解定义时绑定,定义定义,没定义就没绑定咯!~

好的那么假如我们此刻用call来调用一下这个arrowFunc方法

obj2.arrowFunc.call(obj) // Arrow function: Alice

打印的结果是obj的name哦~注意此时创建的箭头函数如果不存下来,那么打印完即销毁!

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值