javascript closure立即调用函数表达式

时间:2016-01-05 11:43:18

标签: javascript closures

我正在尝试更深入地了解javascript闭包,阅读有关该主题的内容,我遇到了许多类似的示例到以下函数:

function idCreator(listOfItems) {
    var i;
    var uniqueID = 100;
    for (i = 0; i < listOfItems.length; i++) {
        listOfItems[i]["id"] = function (j) { 

            return function () {
                return uniqueID + j;
            }()
        }
        (i); 
    }
    return listOfItems;
}

我理解使用IIFE内部函数并将计数器变量作为参数传递的主要概念,所以例如在上面的例子中我们将返回正确的i(索引),而不是我们在结束后得到的值。循环。

我的问题是为什么返回一个匿名函数,不会返回值本身的工作原理相同?

类似的东西:

function iDCreator(listOfItems) {
    var i;
    var uniqueID = 100;
    for (i = 0; i < listOfItems.length; i++) {
        listOfItems[i]["id"] = function (j) { 
                return uniqueID + j;
        }
        (i); 
    }
    return listOfItems;
}

2 个答案:

答案 0 :(得分:0)

根本不需要使用任何功能。

for (i = 0; i < listOfItems.length; i++) {
    listOfItems[i]["id"] = uniqueID + i;
}

在分配稍后将调用的函数时,使用闭包非常有用。它不在这里。看起来代码的作者就被带走了。

答案 1 :(得分:0)

我看到在您提供的示例中使用闭包和IIFE的唯一原因是教学:展示如何与IIFE交换代码,并获得完全相同的结果。此外,它还显示了内部函数如何仍然可以访问外部变量。

正如Quentin所说,在这个例子中,没有其他合理的理由使用闭包和IIFE。它甚至会适得其反(降低性能并混淆代码)。

通过&#34;定义&#34;,IIFE(&#34;立即调用&#34;)稍后不会被调用。它的主要(也可能是唯一的)用途是提供一个函数作用域/闭包(好像它是一个&#34;块&#34;在提供块作用域的其他语言中),同时仍然避免使用正常的函数声明,你必须选择一个可能与其他地方定义的另一个碰撞的标识符。

// Normal function declaration:
function someIdentifier() {}
// Let's immediately call it to execute the code.
someIdentifier();
// what happens if "someIdentifier" was defined somewhere else?
// For example in a previous loop iteration?

这就是为什么作者必须在其for循环中使用IIFE。

在范围/闭包中,您可以使用所需的任何标识符(用于变量和函数声明),同时防止与范围外的标识符发生任何冲突。是使用函数声明,函数表达式还是IIFE。

// Using an Immediately Invoked Function Expression:
(function idForRecursion() { // being a Function Expression rather than a declaration, you can even use an identifier here to be used for recursion, and it will not pollute the global scope.

    var anyIdentifier;
    // If "anyIdentifier" were defined outside, this local definition will "shadow" it for the current closure only, without affecting / polluting the outside definition and value.

    // As in normal closures, you can still access variables outside the IIFE.
    alert(myGlobalVar);
})();

因此,关闭闭包的一个更为教学的例子可能是一个IIFE,其中uniqueID在里面并且递增但是隐藏在全局范围内(通过闭包),这样就没有人可以操纵/干扰它:

var iDCreator = (function () {
    var uniqueID = 100; // initial value.

    return function innerFn(listOfItems) {
        for (var i = 0; i < listOfItems.length; i += 1) {
            listOfItems[i]["id"] = uniqueID;
            uniqueID += 1;
        }
        return listOfItems;
    };
})(); // "iDCreator" is now a reference to the "innerFn" which has a closure with "uniqueID", but the latter is not accessible from global scope.
// Calling "iDCreator" several times gives truly unique id's, incremented from the previous call.