【问题标题】:Javascript nested function losing scopeJavascript嵌套函数失去作用域
【发布时间】:2013-07-07 16:10:46
【问题描述】:

谁能解释一下下面代码的作用域绑定

window.name = "window";

object = {
       name: "object",
       method: function() {
             nestedMethod: function() {
                   console.log(this.name);
             }
             nestedMethod();
       }
}

object.method();  // print 'window'

我认为我的问题更多是关于this...为什么this 会失去作用域并默认为全局作用域?我们创建的所有匿名函数都会在全局范围内运行吗?

【问题讨论】:

  • 你可以尝试使用对象的名称,所以object.name
  • 没有。默认情况下,所有函数都在全局范围内,除非作为属性绑定到对象...
  • @dandavis 这真的不准确。函数本质上根本不会“继续”任何范围。 this 的值由每次调用函数的情况决定。
  • 当我在 node.js 中尝试它时,它会为我打印"object"(一旦我在分配给object 之后放置了;)。
  • nestedMethod: function() { 看起来像一个标签,而不是变量或函数名。无论如何,learn about this from the MDN documentation.

标签: javascript binding scope


【解决方案1】:

你应该像这样声明嵌套函数:

Super.prototype.someFunc = function() {
  this.nestedFunc = function() {}
  //now call it
  this.nestedFunc()
}

【讨论】:

    【解决方案2】:
    window.name = "window";
    
    object = {
        name: "object",
        method: function () {
            var self = this;
            var nestedMethod = function () {
                console.log(self.name); // or object.name without declaring self
            }
            nestedMethod();
        }
    }
    
    object.method(); // print 'object'
    

    保存对象的范围 - 或使用对象本身!

    我们创建的所有匿名函数都会在全局范围内运行吗?

    不,不是所有的匿名函数都失去了它们的作用域,所有的函数作用域都绑定到了全局对象(如果它们没有被特定的this调用,见applycall,见下例)!

    window.name = "window";
    
    object = {
        name: "object",
        method: function () {
            var nestedMethod = function () {
                console.log(this.name);
            }
            nestedMethod.call(this); //change the this arg in the current object scope
            // when you call this function with .call(this) you are changing the value of the nestedMethod's this to the current this, which is object
        }
    }
    
    object.method(); // print 'object'
    

    【讨论】:

    • 你是什么意思所有的功能都作用于全局对象?你是说我可以在全局范围内直接调用nestedMethod?
    • 仅供参考,将 this 称为 scope 是不正确的(至少在我看来,您正在这样做)。
    • “所有函数都作用于全局对象”——我觉得这有点不准确。未绑定this 的函数将在window 的上下文中运行,但作用域仍将是最近的函数。
    • 我的错,已经编辑过了。无论如何@elclanrs 这并不完全正确,即使我们使用.call(thisArg)this 也会更改为全局范围,其中thisArg 定义为nullundefined
    【解决方案3】:

    每当你调用一个函数时,只要在函数内部写func()this就会指向全局对象。在你的情况下,你写:

    nestedMethod();
    

    所以this 里面的nestedMethod 是窗口对象。您可以使用call(或apply)为您的函数调用手动定义上下文:

    nestedMethod.call(this);
    

    【讨论】:

      【解决方案4】:

      任何这样调用的函数:

      someFunction();
      

      将具有全局范围作为this 的值(在非严格模式下)。您可以将外部作用域存储在局部变量中,也可以使用.call().apply()

        nestedMethod.call(this);
      

      【讨论】:

      • 你的意思是任何像这样调用的函数,不管它被调用的范围和定义的位置?
      • @user1389813 是的,没错。任何简单调用的函数(不是使用.call().apply(),不是使用new,也不是通过像foo.myFunc() 这样的对象属性引用)将导致this 的值是window(全局) 对象处于非严格模式,undefined 处于严格模式。
      猜你喜欢
      • 1970-01-01
      • 2013-03-25
      • 2013-04-03
      • 1970-01-01
      • 2016-08-25
      • 1970-01-01
      • 2015-02-09
      • 2019-01-30
      • 2014-07-11
      相关资源
      最近更新 更多