【问题标题】:Difference in these tiny syntax variations for an IIFE? [duplicate]IIFE 这些微小的语法变化有什么不同? [复制]
【发布时间】:2014-02-20 18:22:40
【问题描述】:

有时我会看到:

(function() {
    alert("hi");
})();

有时我会看到:

(function() {
    alert("hi");
}());

注意函数对象的右括号的位置。

有什么区别?我想不通。无论出于何种原因都更可取?

编辑:

另外,这不起作用:

function() {
    alert("hi");
}();

这看起来很奇怪,因为如果用括号括起来是有效的,如示例 2 所示。我不明白为什么将它括在括号中会在这方面改变任何事情。

【问题讨论】:

  • 前两种形式之间存在no语义差异[假设任何先前的表达式都已终止]。还有 are 重复的问题。最后一种情况不起作用,因为它被解析为带有“悬空()”的FunctionDeclaration,而function在前两种形式中是FunctionExpression
  • “我不明白为什么用括号括起来会改变这方面的任何事情” 如果函数定义在括号内,那么解析器知道它只能是一个函数表达式。如果它不在括号内,则解析器认为它是一个函数 declaration 然后抛出一个错误,因为该声明没有名称(函数声明 必须 有一个名称)。

标签: javascript iife


【解决方案1】:

#1 和 #2 之间 100% 没有区别。

#3 很棘手。

你声明这样的函数:

函数 funcName () { }

JS 实际上会遍历您的代码并挑选出所有这样编写的函数声明(在您当前的范围内),然后它甚至会查看该范围内的其余代码。

例如,如果你写:

(function () {
    var myVar = setVar();

    function setVar () { return 1; }
}());

它可以工作,因为 JS 进入了那个作用域,拿起了函数声明,然后查看了你作用域的其余部分(这就是为什么它不会向你抛出 undefined is not a functionreference-error 的原因)。

所以写:

function () { }();

JS 现在会将其视为

function <name-is-missing> () { }
(/* evaluate whatever is in here, when you're ready to run through the scope */);

当然,JS 永远不会达到() 的程度,因为没有名称的声明很重要。

括号是从哪里来的:

(/* 评估这里的内容 */);

#1 和 #2 之间的细微差别是这样的(现实世界的差异 -- 0%):

// on the inside
var end = (/*evaluate*/function () { return 1; }()/*1*/ /*return*/);
console.log(end); // 1;

// on the outside
// step-1
var end = (/*evaluate*/ function () { return 1; } /*return*/);
console.log(end); // function () { return 1; }

// step-2
end();

...除了我作弊。在 JS 中,表达式的整个链在分配左手之前被评估...

var end = (function () { return 1; })/*function(){}*/()/*1*/;
console.log(end); // 1


There are other ways of showing the JS parser that the function is not a declaration:

var bob = function () { return "Bob"; }();
// it's on the right-hand side, so it must be an expression,
// and will be run inline with the rest of the scope

!function () { return "Nobody will get this"; }();
// JS will evaluate whatever's behind the `!` to determine its truthiness
// (and then invert it)

+function () { return "I am not a number!"; }();
// same deal here, as JS attempts to cast the final value to a number

【讨论】:

    猜你喜欢
    • 2011-11-08
    • 2017-09-15
    • 2020-10-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-22
    • 1970-01-01
    • 2015-04-26
    相关资源
    最近更新 更多