【问题标题】:Is this an immediately invoked function expression?这是一个立即调用的函数表达式吗?
【发布时间】:2015-07-22 04:15:10
【问题描述】:

我是一个 javascript 新手,我试图围绕这段代码来思考。 我在这里找到了http://brackets.clementng.me/post/24150213014/example-of-a-javascript-closure-settimeout-inside

我仍然很难理解它。因为它涉及一些我不熟悉的模式。

// output 0-9, seperated by 1 sec delay.
for (var i = 0; i < 10; i++) {
    setTimeout(function(x) { 
        return function() { 
            console.log(x); 
        }; 
    }(i), 1000*i);
}

这段代码中的(i)是什么意思?

function(x) { 
    return function() { 
        console.log(x); 
    }; 
}(i)

我认为这是一个立即调用的函数表达式。 但正确的语法不是:

(function() {
  // some code
})();

【问题讨论】:

标签: javascript function closures


【解决方案1】:

这确实是一个 IIFE。您引用的语法是 0 个参数的 IIFE;您询问的语法是 1 个参数的 IIFE。它将在内部代码中将i 分配给x。比较:

var print0 = function() {
  console.log("Hello!");
};
print0();

(孤立地)等同于

(function() {
  console.log("Hello!");
})();

因此名称:您创建一个函数,然后立即调用它。

然而,如果你想要一个论点,什么都没有改变:

var print1 = function(name) {
  console.log("Hello, " + name);
};
print1("George");

(孤立地)等同于

(function(name) {
  console.log("Hello, " + name);
})("George");

这里的括号确保函数定义将被视为表达式而不是语句。还有其他方法可以确保,一个常见的方法是

!function() {
  console.log("Hello!");
}();

(但有理由更喜欢括号。)由于您将其用作setTimeout 调用的参数,因此它不可能是一个语句,因此这些技巧是不必要的。它仍被称为“立即调用的函数表达式”,因为您仍在构造函数表达式并立即调用它。

这里使用 IIFE 的原因是“捕获”变量i 的值,而不是x 的位置。如果没有关闭技巧,您将获得 10 次超时,全部输出 10(当 console.log 解析时,x 表示的位置值)。

【讨论】:

    【解决方案2】:

    是的,(i) 是调用的参数列表。查看here 以获得详细说明。在这种情况下,分组括号是不必要的,因为它是 setTimeout 函数调用的参数,因此无论如何都是一个表达式。

    术语 IIFE 不仅仅指这种模式的语句形式,其中parenthesis would be necessary

    【讨论】:

      【解决方案3】:

      在您的立即调用函数示例中,括号是可选的。

      (function() {
        // some code
      })();
      

      可以改写为

      function() {
        // some code
      }();
      

      所以示例函数调用中的i 变成了函数定义中的x

      function(x) { // x = 1
          return function() { 
              console.log(x); // x = 1
          }; 
      }(1)
      

      【讨论】:

        猜你喜欢
        • 2018-01-07
        • 1970-01-01
        • 2012-12-28
        • 2017-04-06
        • 1970-01-01
        • 2014-01-28
        • 2016-05-04
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多