在 Javascript 中使用闭包
Posted
技术标签:
【中文标题】在 Javascript 中使用闭包【英文标题】:Using closures in Javascript 【发布时间】:2012-08-28 18:52:14 【问题描述】:我遇到了这个 javascript 代码。
var digit_name = function()
var names = ['zero', 'one','two'];
return function(n)
return names[n];
;
();
alert(digit_name(1));
输出是一个。我知道内部函数被分配给变量 digit_name。外层函数代码后第6行需要加括号是什么?谁能告诉我到底发生了什么?
【问题讨论】:
搜索“javascript 自调用函数”,例如***.com/questions/5367988/…names
变量是匿名函数的本地变量
如果删除第 6 行的双亲,会发生什么?
javascript syntax: function calls and using parenthesis 和 ***.com/questions/592396/… 的可能重复
Immediately-Invoked Function Expression (IIFE)
【参考方案1】:
添加的括号使外部函数执行,如果省略它,它将将外部函数分配给您的 digit_name
而不是内部函数。
【讨论】:
【参考方案2】:您看到的结尾()
使该外部函数立即执行。所以digit_name
最终存储了生成的内部函数,而不是指向外部函数的指针。
欲了解更多信息,请参阅:What is the purpose of a self executing function in javascript?
【讨论】:
【参考方案3】:让我们为这些函数命名,以便更好地理解发生了什么:
var digit_name = function outer()
var names = ['zero', 'one','two'];
return function inner(n)
return names[n];
;
();
alert(digit_name(1));
因此,这里有两个函数在起作用:inner
和 outer
。您正在定义一个名为outer
的函数,其目的是创建一个捕获names
数组的闭包范围,并定义并返回另一个可以访问此闭包的函数。第 6 行的括号表示 调用函数,因此分配给 digit_names
变量的值不是 outer 函数,而是 inner 一个。
【讨论】:
【参考方案4】:var digit_name = function() ...;
=> digit_name
是一个函数
var digit_name = function() ...();
=> digit_name
是函数返回的对象
【讨论】:
【参考方案5】:var digit_name = function() // Create outer function
var names = ['zero', 'one','two']; // Define names array, this is done when the outer function is ran
return function(n) // Return the new inner function, which gets assigned to digit_name
return names[n];
;
(); // Execute the outer function once, so that the return value (the inner function) gets assigned to digit_name
【讨论】:
【参考方案6】:这里有两个非常快速的过程。
如果我们要这样写:
function makeDigitReader () var names; return function (n) return names[n]; ;
var myDigitReader = makeDigitReader();
您会正确猜测 myDigitReader 将被赋予内部函数。
他们正在做的是跳过一个步骤。 通过添加括号,他们所做的就是在函数被定义的那一刻触发它。
所以你正在发生这种情况:
var myDigitReader = function ()
var names = [...];
return function (n) return names[n]; ;
;
myDigitReader = myDigitReader();
看看发生了什么?
您已将内部函数作为新值返回给曾经是外部函数的值。
所以外部函数不存在了,但内部函数仍然可以访问names
数组。
你也可以返回一个对象而不是一个函数。 并且这些对象属性/函数也可以访问最初在函数内部的内容。
通常,您会看到这些立即调用的函数被括在括号中 var myClosure = (function() return ; ());
。
如果您打算运行一个而不将其返回值分配给一个值,那么您需要将它放在括号中,或者在它的前面添加某种操作数,以使编译器对其进行评估。
!function () doStuffImmediately(); (); // does stuff right away
function () doStuffImmediately(); (); // ***ERROR*** it's an unnamed function
希望这能回答您可能遇到的所有问题。
【讨论】:
以上是关于在 Javascript 中使用闭包的主要内容,如果未能解决你的问题,请参考以下文章