关于箭头函数中this的指向问题?

关于箭头函数中this的指向问题

    <script>
        function foo() {
            const test = () => {
                console.log(this)
            }
            test()
        }
        foo()
        let obj = {
            a: 1,
        }
        obj.foo = foo
        obj.foo()
    </script>

在箭头函数中,this引用的是定义箭头函数的上下文。示例代码按理来说应该打印两次window,但结果是一次window,一次obj。

问了好多个AI,AI给的结果都是打印两次window。

阅读 1.8k
avatarAI BotBETA

在JavaScript中,箭头函数不绑定自己的this,它捕获其所在(即包含它定义的)上下文(也称为词法作用域)的this值作为自己的this值。这意味着箭头函数中的this值总是指向定义箭头函数的那个上下文中的this

在你的例子中,test是一个箭头函数,它被定义在foo函数内部。因此,test箭头函数中的this将引用foo函数被调用时的this

让我们一步步分析代码:

  1. 当直接调用foo()时:

    • foo函数中的this在严格模式下是undefined(因为foo是一个普通函数,且不是以任何对象的方法调用的),在非严格模式下,this将指向全局对象(在浏览器中是window)。
    • 由于test是一个箭头函数,它的this值捕获自其外部上下文,即foo函数的this
    • 因此,当调用test()时,它将打印出foo函数中的this值,即window(在非严格模式下)。
  2. 当调用obj.foo()时:

    • 尽管foo被设置为obj对象的一个属性,但是当我们以这种方式调用函数时(即对象的方法),通常函数内部的this会指向该对象(除非函数被显式地绑定到另一个this值或使用箭头函数)。但是,foo中的test是一个箭头函数,所以test中的this不会指向obj
    • 如上所述,test中的this值捕获自foo函数,而foo函数被调用时,它的this(在非严格模式下)仍然是window(因为foo函数本身没有被绑定到obj)。
    • 因此,当通过obj.foo()调用test()时,它同样会打印出window(在非严格模式下)。

所以,无论哪种情况,test箭头函数中的this都会指向window(在非严格模式下)。

如果你的代码是在严格模式下运行的(即在<script>标签中添加"use strict";),那么第一次调用foo()时,this将是undefined(在foo函数中),但是由于你尝试打印this,它会抛出一个错误,因为undefined没有console.log方法。

但是,基于你给出的代码(非严格模式),答案是两次都会打印window

4 个回答

箭头函数没有this,再箭头函数里面访问this,你可以当做是访问一个变量,当前作用域没有this,会向上层作用域进行查找。

test里面访问this,这个this是指向foo中的this,单独运行foo,foo的this指向window,使用obj.foo运行foo,foo的this指向obj

箭头函数定义在 foo 里,它里面的 this 就是 foo 的 this。

obj.foo() 的时候,foo 的 this 是 obj,不是 window

我自己试了一下丢给通义千问一次就给出了正确答案,不清楚你是怎么丢给AI的,但是我觉得回答的挺不错的了:
image.png

新手上路,请多包涵

函数内部的箭头函数(=>)没有自己的this值。它们会捕获其所在上下文的this值作为自己的this值,
1、test是一个箭头函数,所以它捕获的是外部函数foo的this值。
2、因为foo是一个普通函数,且不是作为对象的方法被调用的,所以foo中的this值会是undefined。
3、创建了一个对象obj,并给它添加了一个属性foo,这个属性的值是前面定义的foo函数,foo函数内部的test箭头函数已经捕获了foo函数原来的this值(在这种情况下是undefined)这种是严格模式下,你打印出来第二次是对象obj的是非严格模式下,非严格模式下调用obj对象里面的foo函数,foo函数里面的test是箭头函数,箭头函数绑定其运行时的上下的this,所以指向了obj对象。
有说错的地方,希望各位大佬指出。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏