在JavaScript中,箭头函数不绑定自己的this
,它捕获其所在(即包含它定义的)上下文(也称为词法作用域)的this
值作为自己的this
值。这意味着箭头函数中的this
值总是指向定义箭头函数的那个上下文中的this
。
在你的例子中,test
是一个箭头函数,它被定义在foo
函数内部。因此,test
箭头函数中的this
将引用foo
函数被调用时的this
。
让我们一步步分析代码:
当直接调用foo()
时:
foo
函数中的this
在严格模式下是undefined
(因为foo
是一个普通函数,且不是以任何对象的方法调用的),在非严格模式下,this
将指向全局对象(在浏览器中是window
)。- 由于
test
是一个箭头函数,它的this
值捕获自其外部上下文,即foo
函数的this
。 - 因此,当调用
test()
时,它将打印出foo
函数中的this
值,即window
(在非严格模式下)。
当调用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
。
箭头函数没有this,再箭头函数里面访问this,你可以当做是访问一个变量,当前作用域没有this,会向上层作用域进行查找。
test里面访问this,这个this是指向foo中的this,单独运行foo,foo的this指向window,使用obj.foo运行foo,foo的this指向obj