Javascript 为什么嵌套本地函数将'this'绑定到窗口而不是父窗口
我读了一些,偶然发现了以下代码示例:Javascript 为什么嵌套本地函数将'this'绑定到窗口而不是父窗口,javascript,scope,this,Javascript,Scope,This,我读了一些,偶然发现了以下代码示例: var o = { value: 1, outer: function () { var inner = function () { console.log(this); //bound to global object }; inner(); } }; o.outer(); 它输出窗口 我无法理解为什么this关键字绑定到全局对象(window)而不是父对象(outer)。 如果要从internal的作用
var o = {
value: 1,
outer: function () {
var inner = function () {
console.log(this); //bound to global object
};
inner();
}
};
o.outer();
它输出窗口
我无法理解为什么this
关键字绑定到全局对象(window
)而不是父对象(outer
)。如果要从
internal
的作用域访问outer
,则必须将outer
的this
(这与将outer
本身作为参数传递给其本地internal
函数类似)。因此,正如预期的那样:
var o = {
value: 1,
outer: function () {
var inner = function (that) {
console.log(that); //bound to global object
};
inner(this);
}
};
o.outer();
输出外部
在外部
的作用域中,这个
绑定到对象本身(即外部
),而在内部
的作用域中,它是外部
的局部,这个
被重新绑定到全局对象(即,它覆盖了外部
的绑定),这不是有点荒谬吗
当输入函数代码的执行上下文时,如果«调用者提供的thisArg»为空或未定义,则
此
绑定到全局对象
但以下几点:
var o = {
outer: function () {
var inner = function () {
console.log('caller is ' + arguments.callee.caller);
};
inner();
}
}
输出对象外部
自身:
caller is function () {
var inner = function () {
console.log('caller is ' + arguments.callee.caller);
};
inner();
}
在某一方面,但可能相关,请注意:
在严格模式下,第一个代码段输出
未定义
而不是窗口。这是因为此
是在函数运行时设置的,而不是在定义时设置的
例如:
var o = {
func: function(){
console.log(this);
}
};
调用o.func()
时,您是在o
上下文中进行的,因此它可以按预期工作
现在让我们假设您这样做:
var f = o.func;
f();
这不会像预期的那样起作用。这是因为当您调用f()
时,它没有附加任何上下文,因此此
将成为窗口
您可以通过使用.call
更改this
的值来解决此问题
var f = o.func;
f.call(o); // sets `this` to `o` when calling it
这就是语言的工作原理
每次调用函数时,将重置此
。在嵌套(内部)函数中,它不会像其他(显式声明的)变量那样从封闭范围继承值
默认情况下,此
将设置为窗口
,除非该函数作为以下方式调用:
myObj.func(arg1,…)
或
函数调用(myObj,arg1,…)
或
函数应用(myObj[arg1,…])
在这种情况下,此
将等于myObj
以任何其他方式调用函数,即使它最初被定义为对象的属性(即var func=myObj.func;func()
也将使用window
)
还有一个名为.bind
的实用函数,它包装函数引用,这样您就可以提供一个特定的值,该值将始终用作此
:
var myFunc = myObj.func; // obtain reference to func
var bound = myFunc.bind(someOtherObj); // bind it to "someOtherObj"
bound(); // this === someOtherObj
bound.call(myObj) // this still === someOtherObj
这是因为您调用internal
-internal();
的方式。this
的值是通过调用函数的方式设置的。无论如何,internal
与outer
没有关系,它只是一个局部变量。如果使用console.log(this)内部的外部的并将其命名为:var a=o.outer;a();
,您会看到窗口的。您可能认为这是胡说八道,但它是这样设计的-您需要学习如何正确使用它。“ECMAScript规范规定,在输入函数代码的执行上下文时,如果«caller provided thisArg»为null或未定义,则它绑定到全局对象。”-您没有回答自己的问题吗?internal()
没有指定thisArg。@Ian那么,调用的范围根本不重要吗?@NadirSampaoli我不认为如此,至少就如何设置this
的值而言。@Fabriciomattéyes,internal()
未指定thisArg
,但它是否对应于参数.callee.caller
?