使用嵌套函数返回的简单闭包与闭包
var names = ["zero", "one", "two", "three", "four", "five", "six", "seven", "eight"]; var digit_name = function(n){ return names[n]; } //Execute digit_name(0)
与
var digit_name = (function() { var names = ["zero", "one", "two", "three", "four", "five", "six", "seven", "eight"]; return function(n) { return names[n]; } })();
然后像这样执行:
digit_name(2)
我知道这些都是闭包,但我也认为两者的设置方式存在一些根本区别。 有人可以指出这两种设置有多么不同(特别是考虑到两者都完成相同的工作)? 将全局变量附加到’window’与嵌套函数以模拟私有变量是我能想到的。
编辑 – 我现在很困惑是否将第一个设置视为关闭…使用chrome,我调查了两个设置..
var digit_name = (function() { var names = ["zero", "one", "two", "three", "four", "five", "six", "seven", "eight"]; return function(n) { return names[n]; } })(); undefined console.dir(digit_name) function anonymous(n) arguments: null caller: null length: 1 name: ""prototype: Object __proto__: function() Closure names: Array[9] With Block: CommandLineAPI Global: Window
但是对于chrome的第一个function,
var names = ["zero", "one", "two", "three", "four", "five", "six", "seven", "eight"]; var digit_name = function(n){ return names[n]; } undefined console.dir(digit_name) function digit_name(n) arguments: null caller: null length: 1 name: "" prototype: digit_name __proto__: function() With Block: CommandLineAPI Global: Window
您可以看到Chrome明确指出第一次设置是否存在关闭,但第二次设置没有。
我知道这些都是封闭的
正确。
但我也认为两者的设置方式存在一些根本区别。
错误。
这个:
var names = ["zero", "one", "two"]; // outer scope variable var digit_name = function (n) { // closure -------+ return names[n]; // outer scope variable reference | } // ---------------+
还有这个
var digit_name = (function() { // closure --------+ var names = ["zero", "one", "two"]; // outer scope variable | return function(n) { // closure ---+ | return names[n]; // outer scope variable reference | | } // -----------+ | })(); // ----------------+
在function上是完全相同的,唯一真正的区别是闭包的数量。
JavaScript中的每个function
都会创建一个闭包,就这么简单。
不要让设置闭包的不同方式(函数语句,函数表达式或立即执行的函数表达式)让您感到困惑,最终它们都是相同的。
首先让我们用简单的词语来理解闭包。
Closure是一个内部函数,可以访问外部函数的变量(包装函数)。
现在,闭包函数具有访问具有三个不同范围的变量的神奇力量。
- 它的变量是局部范围。
- 它的外部函数范围的变量。
- 全球范围的变量。
现在,如果我们查看您描述的两种情景。
第一:
var names = ["zero", "one", "two", "three", "four", "five", "six", "seven", "eight"]; var digit_name = function(n){ return names[n]; } //Execute digit_name(0)
这里变量names
和digit_name
有一个全局范围,因为它是直接声明的,在浏览器的情况下是window
(即你可以使用window.names
访问它)。 现在,存储在digit_name
的函数显然正在访问全局变量。
所以这里
closure
没有图片。 (这是访问全局变量的函数的一个简单示例。
第二:
var digit_name = (function() { var names = ["zero", "one", "two", "three", "four", "five", "six", "seven", "eight"]; return function(n) { return names[n]; } })();
这里digit_name
有一个全局作用域,而且存储在digit_name
的函数是一个closure
,因为它被包装在一个外部函数( anonymous
)中,该函数在声明后立即被调用。 现在变量names
具有局部范围,因为它在函数内声明,而closure
函数正在访问该函数的局部变量,因为它属于外(包装)函数的范围。
这是闭包function的一个例子。
我希望这有助于你了解closure
。
有关更多信息,您可以在此处查看更多示例
为了理解范围,您可以参考这个答案