#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