首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >更深入地理解Javascript中的闭包

更深入地理解Javascript中的闭包
EN

Stack Overflow用户
提问于 2013-04-04 02:18:56
回答 4查看 856关注 0票数 13

我读到了答案上的评论,然后看到了这句话

闭包不保留foo的状态,而是创建一个包含(1)返回函数和(2)返回时引用的所有外部变量的特殊作用域。这个特殊的作用域称为闭包。

好吧,到目前为止还不错。下面是我不知道的有趣的部分:

很好的例子..。如果在foo中定义了另一个变量,即返回函数中没有引用,那么它将不存在于闭包范围中。

我想这是有道理的,但除了记忆的使用/性能之外,这还有什么意义呢?

问题 --如果范围中的所有变量都包含在闭包中,那么对于当前的模型,我能做什么呢?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2013-04-04 02:28:43

我觉得你把这句话看得太当真了。注释只是说您不能在函数作用域之外访问它(它不能公开访问),而不是说它在函数中根本不可用。无论什么情况,返回的函数都可以访问所有外部函数作用域。如果内部函数不能提供访问外部函数的方法,那么就不能访问外部函数之外的范围。

例如,该表达式的计算结果为4:

代码语言:javascript
运行
复制
function testClosure(){
 var x = 2;
    return function(y){
        alert(eval(y));
    }

}

var closure = testClosure();

closure("x+2");  //4

http://jsfiddle.net/dmRcH/

因此,尽管没有直接引用,x还是可用的。

进一步研究

看来chrome和firefox至少试图优化这一点,因为如果您没有提供任何方法来引用x变量,它就不会在调试器中显示为可用。用断点运行关闭显示x在Chrome 26和火狐18上不可用。

http://jsfiddle.net/FgekX/1/

但这只是内存管理细节,而不是语言的相关属性。如果有任何可能的方法可以引用变量,那么它就会被传递,我怀疑其他浏览器可能不会以同样的方式优化这个变量。按照规范编写代码总是比对实现进行编码更好。在这种情况下,规则实际上是:“如果您有任何可能的方式访问它,它将是可用的”。而且,不使用,因为它确实会阻止代码对任何进行优化。

票数 11
EN

Stack Overflow用户

发布于 2013-04-04 02:43:52

如果在foo中定义了另一个未在返回函数中引用的var,则它将不存在于闭包范围中。

这并不完全准确;变量是闭包作用域的一部分,尽管它可能不会在函数本身内直接引用(通过查看函数代码)。不同之处在于引擎如何优化未使用的变量。

例如,在使用DOM元素时,闭包作用域中的未使用变量会导致内存泄漏(在某些引擎上)。以这个经典的例子为例:

代码语言:javascript
运行
复制
function addHandler() {
    var el = document.getElementById('el');
    el.onclick = function() {
        this.style.backgroundColor = 'red';
    }
}

来源

在上面的代码中,内存是泄漏的(至少在IE和Mozilla中都是如此),因为el是click处理程序函数的闭包作用域的一部分,尽管它没有被引用;这导致循环引用无法被删除,因为它们的垃圾收集是基于引用计数的。

另一方面,Chrome使用的是不同垃圾收集器

在V8中,对象堆被分割成两个部分:创建对象的新空间,以及在垃圾回收周期中幸存的对象被提升到的旧空间。如果在垃圾回收周期中移动对象,V8将更新指向该对象的所有指针。

这也被称为世代或临时垃圾收集器。尽管更复杂,但这种类型的垃圾收集器可以更准确地确定是否使用了变量。

票数 3
EN

Stack Overflow用户

发布于 2013-04-04 02:36:35

JavaScript没有固有的隐私感,所以我们使用函数范围(闭包)来模拟这个功能。

您所引用的答案是模块模式的一个示例,Addy在解释学习JavaScript设计模式中的重要性时做了非常出色的工作

模块模式使用闭包封装“隐私”、状态和组织。它提供了一种将公共和私有方法和变量混合在一起的方法,防止碎片泄漏到全局范围,并意外地与另一个开发人员的接口发生冲突。使用此模式,只返回一个公共API,将闭包中的其他所有内容保持为私有。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15801471

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档