为什么封闭值会丢失?

问题描述:

我遇到了以下问题:为什么封闭值会丢失?

function Parent(value) { 
    var callback = function() { 
     console.log(value); 
     //actually the following line was found in the code 
     var value; //<- hoisting, takes effect first 
    } 
    callback(); 
} 

Parent(); //undefined 
Parent('Wow!'); //undefined, closure value was lost?! 

两个上级呼叫记录“未定义”的消息,但我真的希望看到“哇!”第二次通话的价值。

问题都可以在这里重现:http://jsfiddle.net/5tgsj37e/3/

相关问题:Why does this closure-scoped variable lose its value?

+1

为什么你有'console.log('value');'?这不会每次都记录“价值”吗?它在控制台中是“未定义的”吗?而且,正如@charlietfl所说,“url”没有定义,所以AJAX可能根本不起作用。这是你的完整代码吗? –

+3

哪里定义了“url”?另外'Parent()'不会返回任何东西,所以它没有意外的记录未定义。你到底想要在这里发生什么? – charlietfl

+0

已更新var url = anyUrl;和console.log(value); – Spirit

的原因是提升:

(function Parent(value) { 
    var child = function() { 
     console.log(value); 
     var value; //hoisting clears closure value 
    } 
    child(); 
}('Wow!')); 

虽然没有大碍:

(function Parent(value) { 
    var child = function() { 
     console.log(value); 
     //var value; 
    } 
    child(); 
}('Wow!')); 

我没有注意到父函数VAR值昨天。

代码示例:http://jsfiddle.net/5tgsj37e/3/


关于代码风格的其他注意事项。

严格模式:将孩子放在父母之外将会创建一个全局。因此,在使用闭包时,应将“严格使用”严格模式视为一种良好做法。

显式关闭声明如果要在子函数中使用闭包值,最好将Child明确包装到闭包中。如果有一天你的孩子开始生活在父母之外,这将阻止全局变量的创建。这也会引发一个没有价值的错误。

(function Parent(value) { 
    (function(childValue) { 
     var child = function() { 
      console.log(childValue); 
     } 
     child(); 
    )(value)); 
}('Wow!')); 

备注关闭:关闭是每个函数调用创建的,而不是每个函数声明。

在这个例子中,Parent没有return语句,因此总是返回undefinedParent也不会自行调用console.log,因此不会将任何内容记录到控制台。在其中创建并分配到var callback的匿名函数调用console.log。然后通过您的ajaxCall函数将此成功回调传递给jQuery.ajax()

匿名callback函数将在异步ajax请求成功后调用。对于AJAX请求,当然根据jQuery documentation成功。

至于结果似乎不可能再现与代码是,或许有你的Parent功能的地方,删除value参数或以其他方式将其设置为undefined额外的代码。由内部函数关闭的参数和变量不会被垃圾收集,除非它们具有0引用计数。

+0

而在我的情况字符串值似乎是垃圾收集。 – Spirit

+0

正在使用什么JavaScript引擎? – Nicholas

+0

这是Chrome浏览器。我已经删除了ajax调用,问题仍然被复制。所以这是一个关闭问题。 – Spirit