所以,我有如下 3 个函数:
function a() {
arguments[0]();
}
function b(fn) {
fn();
}
function c() {
console.log(this);
}
现在,考虑输出:
a(c) // Arguments
b(c) // Window
a(() => {console.log(this}) // Window
b(() => {console.log(this)}) // Window
为什么 a(c)
在所有其他情况下都是窗口(考虑非严格)时输出参数?
在 JavaScript 中,this
通常指调用函数的对象(除非它是箭头函数)。因此,例如,如果我们做这样的事情:
var obj = { fun: function() { console.log(this); } }
var obj1 = { fun: obj.fun, otherProperty: 123 }
obj.fun(); // equivalent to obj["fun"]()
obj1.fun(); // equivalent to obj1["fun"]()
我们会发现,在第一次调用中,this
引用了 obj
,而在第二次调用中,它引用了 obj1
,尽管它们是相同的功能。
现在,arguments
变量是一个对象,它存储传递给函数的所有参数。如果一个参数是一个函数,并且您通过 arguments
对象访问它,它就成为调用该函数的“父”对象,并且成为新的 this
函数的执行上下文。你可以认为你的情况等同于这样的事情:
function c() {
console.log(this);
}
var arguments = { "0" : c }
arguments["0"]() // will log the arguments object
在您的第二次调用 (b(c)
) 中,作为参数传递的函数直接在父函数内部调用,而不通过代理对象访问它 - 在这种情况下 this
将从父执行范围复制,即 window
。
在第三个和第四个示例中,两个函数都是使用箭头函数定义的,它从创建它们的上下文中保存 this
的值,并防止这个值被更改。
关于箭头函数的更多信息:Arrow functions