Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/EmptyTag/127.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 为什么嵌套本地函数将'this'绑定到窗口而不是父窗口_Javascript_Scope_This - Fatal编程技术网

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