Difference in these tiny syntax variations for an

2019-03-07 01:41发布

Sometimes I see this:

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

And sometimes I see this:

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

Note the placement of the closing paren for the function object.

What is the difference? I can't figure it out. Is either preferable for any reason?

Edit:

Also, this does not work:

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

Which seems weird, since it is valid if wrapped in parentheses, as in example 2. I don't understand why wrapping it in parentheses changes anything in that respect.

1条回答
别忘想泡老子
2楼-- · 2019-03-07 01:56

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
查看更多
登录 后发表回答