-1

有时我会看到:

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

有时我会看到:

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

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

有什么区别?我想不通。出于任何原因,两者都更可取吗?

编辑:

此外,这不起作用:

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

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

4

1 回答 1

1

100% no difference between #1 and #2, at all.

#3 is tricky.

You declare functions like this:

function funcName () { }

JS will actually go through your code and pick out all of the function declarations which are written like that (within your current scope), before it even looks at the rest of the code in that scope.

So for instance, if you write:

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

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

It works, because JS entered that scope, picked up the function declaration, and then looked at the rest of your scope (which is why it doesn't throw an undefined is not a function reference-error at you).

So writing:

function () { }();

JS will now see that as

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

Of course, JS will never make it as far as the () because a declaration with no name is a big deal.

Which is where the parens come in:

(/* evaluate what's in here */);

The subtle difference between #1 and #2 is this (real-world difference -- 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();

...except that I cheated. In JS, the entire chain of the expression is evaluated before the left-hand is assigned...

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
于 2014-01-29T05:46:22.567 回答