当您在 Javascript 中调用顶级函数时,函数内的this关键字引用默认对象(如果在浏览器中,则为窗口)。我的理解是,这是将函数作为方法调用的一种特殊情况,因为默认情况下它是在窗口上调用的(如 John Resig 的书,JavaScript Ninja 的秘密,第 49 页中所述)。事实上,以下代码中的两个调用都是相同的。
function func() {
return this;
}
// invoke as a top-level function
console.log(func() === window); // true
// invoke as a method of window
console.log(window.func() === window); // true
到目前为止一切顺利......现在这是我不明白的部分:
当一个函数嵌套在另一个函数中并在没有指定要调用的对象的情况下被调用时,函数内部的this关键字也指的是 window。但是不能在窗口上调用内部函数(参见下面的代码)。
function outerFunc() {
function innerFunc() {
return this;
}
// invoke without window.* - OK
console.log(innerFunc() === window); // true
// invoke on window
//window.innerFunc(); - error (window has no such method)
console.log(window.innerFunc) // undefined
}
outerFunc();
嵌套函数在窗口上不可用是完全有道理的,因为它毕竟是嵌套的......但是我不明白为什么 this 关键字指的是窗口,就好像函数是在窗口上调用的一样。我在这里想念什么?
编辑
以下是以下优秀答案的摘要以及我的一些后续研究。
说“正常”调用函数与将其作为window的方法调用是一样的,这是不正确的。只有在全局定义函数时,这才是正确的。
函数上下文(this关键字的值)不取决于函数的定义位置/方式,而是取决于调用它的方式。
假设代码没有在严格模式下运行,“正常”调用函数会将函数上下文设置为窗口(在浏览器中运行时,或在其他环境中运行相应的全局对象)。
上述规则的一个例外是使用bind来创建函数。在这种情况下,即使“正常”调用该函数,它也可能具有除window之外的上下文。也就是说,在这种情况下,上下文取决于您如何创建函数,而不是如何调用它。虽然严格来说这并不准确,因为bind创建了一个新函数,该函数使用apply内部调用给定函数。该新函数的上下文仍将由调用它的方式确定,但它通过使用apply屏蔽了它在内部调用的函数的上下文。
通过“正常”调用,我指的是以下简单的调用方式:
myFunction();
为了完成图片,这里简要介绍了其他调用方式和相应的上下文:
作为对象(方法)的属性——上下文就是对象
使用 apply 或 call - 明确指定上下文
使用new运算符(作为构造函数) - 上下文是一个新创建的对象
如有必要,请随时更新上述内容,以使有类似问题的人受益。谢谢!