IIFE的这些微小语法变体的差异?

时间:2014-01-29 05:22:42

标签: javascript iife

有时候我会看到这个:

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

有时候我会看到这个:

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

注意函数对象的闭合元素的位置。

有什么区别?我无法弄清楚。是出于任何原因要么更好?

编辑:

此外,这不起作用:

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

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

1 个答案:

答案 0 :(得分:1)

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

#3很棘手。

你声明这样的函数:

function funcName(){}

JS实际上会查看你的代码,并在它查看该范围内的其余代码之前,选择所有类似的函数声明(在当前作用域内)。

例如,如果你写:

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

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

它有效,因为JS进入了该范围,获取了函数声明,然后查看了你的范围的其余部分(这就是为什么它不会引发undefined is not a function引用错误。)< / p>

所以写作:

function () { }();

JS现在将其视为

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

当然,JS永远不会把它变成(),因为没有名字的声明是一件大事。

这是parens的用武之地:

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

#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