Javascript-命名空间和闭包有什么区别?

8
在Javascript中,命名空间和闭包有什么区别?它们在我看来非常相似。
编辑:
具体而言,this article讨论了命名空间和闭包,并且有类似以下语句的句子:
现在,我们仍然会遇到希望声明变量但不自然适应命名空间对象结构的情况。但是我们不希望这些变量具有全局作用域。这就是自动调用函数的作用。
它继续提供了一个很像闭包的“对象命名空间”。在我看来,命名空间就是闭包...但也许不是...?请帮忙确认。

2
请详细阐述您对“命名空间”的定义。 - J. Holmes
JavaScript 没有命名空间。那这个术语是什么意思? - Mark Reed
1
在JavaScript中,“命名空间”没有一个明确的意义,因为有许多方法可以将符号分隔成空间(包括使用闭包)。展示一些代码。 - Francis Avila
3个回答

24

命名空间本质上是一个没有有趣属性的Object,你可以把东西塞进去,以便在范围内不会出现许多名称相似或冲突的变量。因此,例如:

MyNS = {}
MyNS.x = 2
MyNS.func = function() { return 7; }

闭包是指函数“保留”了不在其作用域内定义的变量的值,即使这些变量已经超出了其生命周期。看下面的例子:

function makeCounter() { 
   var x = 0;
   return function() { return x++; }
}
如果我执行c = makeCounter()并反复调用c(),我将获得 0, 1, 2, 3, ...。这是因为makeCounter定义的内部匿名函数的作用域“封闭”了x,因此它引用x即使x不在作用域内仍然有效。
值得注意的是,如果我执行d = makeCounter()d()将从0开始计数。这是因为cd获取x的不同实例。

这是一个非常好的答案 - 谢谢!不过我需要一些时间来思考 :) - Ben
+1,我终于明白闭包了(我试了2-3个教程,总是放弃)。 - ajax333221
是的,这是我见过的最简洁和有用的闭包解释 - 谢谢!现在我明白了。 - iono
我觉得这是一个关于闭包的很好的答案,但我仍然不清楚它们与命名空间的区别在哪里。你从哪里获取命名空间的定义,它非常具体,而我对命名空间的印象只是一个命名上下文,其中没有两个对象可以拥有相同的名称。在我看来,这意味着闭包是命名空间的一种类型。 - snuggles

5

命名空间通常是将所有全局变量作为一个主要的全局变量下的属性放置,从而只添加一个新的真正顶级全局变量。它可以防止全局命名空间的污染,并减少与其他全局变量冲突的机会。

命名空间的示例:

var YUI = {};
YUI.one = function(sel) {...};
YUI.two = function(sel) {...};
YUI.three = function(sel) {...};

顶级全局命名空间YUI中有一个新项目,但是通过YUI命名空间对象,有多个全局可访问的项目。

闭包是一个函数块,由于对函数内部部分的持久引用而持续存在于函数正常执行完成之后。

function doSometing() {
    var x = 10;
    setTimer(function() {
        // this gets called after doSomething() has finished executing
        // but because of the function closure, the variables 
        // inside of the parent scope like x are still accessible
        x += 10;
    }, 1000);
}

2

http://jibbering.com/faq/notes/closures/

闭包是由在函数调用的执行上下文中创建的函数对象返回并将对该内部函数的引用分配给另一个对象的属性,或者直接将对这样的函数对象的引用分配给全局变量、全局可访问对象的属性或作为外部函数调用的参数传递的对象而形成的。

命名空间只是一种约定,用于创建对象以避免在全局范围内混杂变量。


1
欢迎来到SO,@GeoffreyHing!感谢您的帮助,但我认为“闭包”段落过于复杂和极易混淆......但命名空间解释清晰简明,+1。 - Ben

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接