那些自动执行的匿名函数(又名IIFE)实现有什么区别?

What is the difference between those self-executing anonymous function (aka IIFE) implementation

本文关键字:实现 IIFE 什么 区别 又名 执行 函数 那些      更新时间:2023-09-26

在许多书籍/博客文章中,自调用匿名函数模式是这样写的:

(function() {
  var foo = 'bar';
})();

然而,在此运行JSLint会给出这个错误:

将调用移动到包含该函数的父类中。

。把它改成这样:

(function() {
  var foo = 'bar';
}());

    为什么第一个实现对JSLint来说不够好?有什么不同?
  1. 首选的形式是什么?JSLint总是正确的吗?
  2. 为什么它工作?毕竟function(){}()抛出了SyntaxError: Unexpected token (
    但是用parent包装它使它突然工作?例如 ( function(){}() ) ——没问题
    (毕竟这是JavaScript,而不是Lisp,那么包装双亲对语法错误的影响是什么呢?)

EDIT:这有点像这个的后续(我不会说完全重复):JSLint错误:"将调用移动到包含函数的父类",所以我的主要问题是#3,为什么它能工作?

我不知道Crockford的观点是如何形成的,但我可以解释为什么在parent中包装是有效的。

JavaScript中的函数function() { ... }语法可以表示两种不同的东西:函数声明或函数表达式。

函数声明是一个语句,它以指定的名称在当前作用域中定义函数。

function example() { 
    alert("Hello World");
}
example();

函数表达式是一个表达式,求值为一个新的Function实例。

var secondExample = function example() {
    alert("Hello World");
};
secondExample();
example(); // <-- throws an Error: example is not defined.

语法的出现是函数声明还是函数语句取决于解析器所期望的内容。JavaScript的解析器很简单。它不会向前看并注意到函数后面跟着(),因此它应该将其视为表达式。它只在一行的开头看到function,因此将其视为一条语句,当它后面跟着()时会导致语法错误。当你把它用圆括号括起来时,解析器期望的是一个表达式,它可以工作。

用括号括起来(无论放在哪里)是最清晰的方法,但是任何导致解析器期望表达式的方法都可以工作。例如,按位NOT操作符~:

~function() {
    alert("Hello World");
}();

1.

显然这是约定的问题。第一个示例显示了"缺乏约定"(来源)。就实际差异而言,没有任何差异。

2。在这种情况下,我更喜欢你的第一个例子,但这只是我的惯例。JSLint通常是正确的。所以如果你想遵循它们的命名约定,那么当它显示基于约定的警告时,遵循约定是有意义的。

3。

之所以有效,是因为将function(){}包装在()中使其成为表达式,一旦与最终的()配对,就会立即调用它。因此,您有一个立即调用的函数表达式。