在 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));

因此,这里有两个函数在起作用:innerouter。您正在定义一个名为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 中使用闭包的主要内容,如果未能解决你的问题,请参考以下文章

对JavaScript中闭包的理解

我从来不理解JavaScript闭包,直到有人这样向我解释它...

JavaScript 闭包

javascript中闭包的具体实际应用

javascript中闭包最简单的简绍

什么是javaScript闭包