我读到了答案上的评论,然后看到了这句话
闭包不保留foo的状态,而是创建一个包含(1)返回函数和(2)返回时引用的所有外部变量的特殊作用域。这个特殊的作用域称为闭包。
好吧,到目前为止还不错。下面是我不知道的有趣的部分:
很好的例子..。如果在foo中定义了另一个变量,即返回函数中没有引用的,那么它将不存在于闭包范围中。
我想这是有道理的,但除了记忆的使用/性能之外,这还有什么意义呢?
问题 --如果范围中的所有变量都包含在闭包中,那么对于当前的模型,我能做什么呢?
发布于 2013-04-04 02:28:43
我觉得你把这句话看得太当真了。注释只是说您不能在函数作用域之外访问它(它不能公开访问),而不是说它在函数中根本不可用。无论什么情况,返回的函数都可以访问所有外部函数作用域。如果内部函数不能提供访问外部函数的方法,那么就不能访问外部函数之外的范围。
例如,该表达式的计算结果为4:
function testClosure(){
var x = 2;
return function(y){
alert(eval(y));
}
}
var closure = testClosure();
closure("x+2"); //4http://jsfiddle.net/dmRcH/
因此,尽管没有直接引用,x还是可用的。
进一步研究
看来chrome和firefox至少试图优化这一点,因为如果您没有提供任何方法来引用x变量,它就不会在调试器中显示为可用。用断点运行关闭显示x在Chrome 26和火狐18上不可用。
http://jsfiddle.net/FgekX/1/
但这只是内存管理细节,而不是语言的相关属性。如果有任何可能的方法可以引用变量,那么它就会被传递,我怀疑其他浏览器可能不会以同样的方式优化这个变量。按照规范编写代码总是比对实现进行编码更好。在这种情况下,规则实际上是:“如果您有任何可能的方式访问它,它将是可用的”。而且,不使用,因为它确实会阻止代码对任何进行优化。
发布于 2013-04-04 02:43:52
如果在foo中定义了另一个未在返回函数中引用的var,则它将不存在于闭包范围中。
这并不完全准确;变量是闭包作用域的一部分,尽管它可能不会在函数本身内直接引用(通过查看函数代码)。不同之处在于引擎如何优化未使用的变量。
例如,在使用DOM元素时,闭包作用域中的未使用变量会导致内存泄漏(在某些引擎上)。以这个经典的例子为例:
function addHandler() {
var el = document.getElementById('el');
el.onclick = function() {
this.style.backgroundColor = 'red';
}
}在上面的代码中,内存是泄漏的(至少在IE和Mozilla中都是如此),因为el是click处理程序函数的闭包作用域的一部分,尽管它没有被引用;这导致循环引用无法被删除,因为它们的垃圾收集是基于引用计数的。
另一方面,Chrome使用的是不同垃圾收集器
在V8中,对象堆被分割成两个部分:创建对象的新空间,以及在垃圾回收周期中幸存的对象被提升到的旧空间。如果在垃圾回收周期中移动对象,V8将更新指向该对象的所有指针。
这也被称为世代或临时垃圾收集器。尽管更复杂,但这种类型的垃圾收集器可以更准确地确定是否使用了变量。
发布于 2013-04-04 02:36:35
JavaScript没有固有的隐私感,所以我们使用函数范围(闭包)来模拟这个功能。
您所引用的答案是模块模式的一个示例,Addy在解释学习JavaScript设计模式中的重要性时做了非常出色的工作
模块模式使用闭包封装“隐私”、状态和组织。它提供了一种将公共和私有方法和变量混合在一起的方法,防止碎片泄漏到全局范围,并意外地与另一个开发人员的接口发生冲突。使用此模式,只返回一个公共API,将闭包中的其他所有内容保持为私有。
https://stackoverflow.com/questions/15801471
复制相似问题