Advanced JavaScript: Why is this function wrapped in parentheses? [duplicate]
Asked Answered
M

4

133

Possible Duplicate:
What is the (function() { } )() construct in JavaScript?

I came across this bit of JavaScript code, but I have no idea what to make out of it. Why do I get "1" when I run this code? What is this strange little appendix of (1) and why is the function wrapped in parentheses?

(function(x){
    delete x;
    return x;
})(1);
Munroe answered 29/1, 2012 at 14:17 Comment(0)
W
278

There are a few things going on here. First is the immediately invoked function expression (IIFE) pattern:

(function() {
  // Some code
})();

This provides a way to execute some JavaScript code in its own scope. It's usually used so that any variables created within the function won't affect the global scope. You could use this instead:

function foo() {
  // Some code
}
foo();

But this requires giving a name to the function, which is not always necessary. Using a named function also means at some future point the function could be called again which might not be desirable. By using an anonymous function in this manner you ensure it's only executed once.

This syntax is invalid:

function() {
  // Some code
}();

Because you have to wrap the function in parentheses in order to make it parse as an expression. More information is here: http://benalman.com/news/2010/11/immediately-invoked-function-expression/

So to recap quickly on the IIFE pattern:

(function() {
  // Some code
})();

Allows 'some code' to be executed immediately, as if it was just written inline, but also within its own scope so as not to affect the global namespace (and thus potentially interfere with or be interfered with by, other scripts).

You can pass arguments to your function just as you would a normal function, for example,

(function(x) {
  // Some code
})(1);

So we're passing the value '1' as the first argument to the function, which receives it as a locally scoped variable, named x.

Secondly, you have the guts of the function code itself:

delete x;
return x;

The delete operator will remove properties from objects. It doesn't delete variables. So;

var foo = {'bar':4, 'baz':5};
delete foo.bar;
console.log(foo);

Results in this being logged:

{'baz':5}

Whereas,

var foo = 4;
delete foo;
console.log(foo);

will log the value 4, because foo is a variable not a property and so it can't be deleted.

Many people assume that delete can delete variables, because of the way autoglobals work. If you assign to a variable without declaring it first, it will not actually become a variable, but a property on the global object:

bar = 4; // Note the lack of 'var'. Bad practice! Don't ever do this!
delete bar;
console.log(bar); // Error - bar is not defined.

This time the delete works, because you're not deleting a variable, but a property on the global object. In effect, the previous snippet is equivalent to this:

window.bar = 4;
delete window.bar;
console.log(window.bar);

And now you can see how it's analogous to the foo object example and not the foo variable example.

Waylen answered 29/1, 2012 at 17:12 Comment(4)
Very well put explanation. Also, as a side-note, I saw Douglas Crockford mention in a talk that he prefers (function() {}()); effectively wrapping the whole IIFE in parens for clarity - more expressive.Disenthrone
comparing to the wiki link, the parens are wrapping the whole thing, does it make any differences?Silly
So in (function(x){ delete x; return x; })(1);, delete x has no effect whatsoever right? Because x is a variable, not a property. Hence delete x does not have any effect right?Callao
@Callao yes, exactlyWaylen
W
12

It means you created an anonymous function, and call it with parameter 1.

It is just the same as:

function foo(x) {
    delete x;
    return x;
}
foo(1);
Warnke answered 29/1, 2012 at 14:19 Comment(2)
I would use a var foo = function(){} avoid confusing function statements and function expressions.Nitrogen
@missingno They are the same.Warnke
Q
3

The reason that you still get 1 returned is that the delete keyword is for removing properties of objects. The rest is as others have commented, anything wrapped in brackets executes as a function, and the second set of brackets are the arguments passed to that block.

Here's the MDN reference for delete, and the MDN reference for closures, which discusses also anonymous functions.

Quetzalcoatl answered 29/1, 2012 at 14:25 Comment(0)
N
2

People normally call these "Immediately Invoked Function Expressions" or "Self Executing Functions".

The point of doing this is that variables declared inside that function do not leak to the outside.

Nitrogen answered 29/1, 2012 at 14:44 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.