Javascript嵌套函数失去作用域

Posted

技术标签:

【中文标题】Javascript嵌套函数失去作用域【英文标题】:Javascript nested function losing scope 【发布时间】: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. 【参考方案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 处于严格模式。

以上是关于Javascript嵌套函数失去作用域的主要内容,如果未能解决你的问题,请参考以下文章

013.Python之函数嵌套名称空间与作用域闭包函数

Javascript基础

python学习第三十一天函数的嵌套及函数的作用域

Python基础-----函数嵌套及作用域

函数的嵌套和作用域

python 函数嵌套及作用域