(...()) VS. (...)() in JavaScript Closures

(...()) vs. (...)() in javascript closures

There's no difference. Both are valid ways to get the JavaScript parser to treat your function as an expression instead of a declaration.

Note that + and ! will also work, and are sometimes used by minifiers to save a character of size:

+function() {  
var foo = 'bar';
}();

!function() {
var foo = 'bar';
}();

EDIT

As @copy points out, for completeness, ~ and - will also work.

-function() {  
var foo = 'bar';
}();

~function() {
var foo = 'bar';
}();

How do JavaScript closures work?

A closure is a pairing of:

  1. A function and
  2. A reference to that function's outer scope (lexical environment)

A lexical environment is part of every execution context (stack frame) and is a map between identifiers (i.e. local variable names) and values.

Every function in JavaScript maintains a reference to its outer lexical environment. This reference is used to configure the execution context created when a function is invoked. This reference enables code inside the function to "see" variables declared outside the function, regardless of when and where the function is called.

If a function was called by a function, which in turn was called by another function, then a chain of references to outer lexical environments is created. This chain is called the scope chain.

In the following code, inner forms a closure with the lexical environment of the execution context created when foo is invoked, closing over variable secret:

function foo() {
const secret = Math.trunc(Math.random() * 100)
return function inner() {
console.log(`The secret number is ${secret}.`)
}
}
const f = foo() // `secret` is not directly accessible from outside `foo`
f() // The only way to retrieve `secret`, is to invoke `f`

Please explain the differences between this Immediately-Invoked Function Expression and Self Invoked Anonymous Function

There is no difference at all between two variants of code.

Moreover, actually parenthesis are redundant there. It'd work even if you write this piece of code the following way:

// Go
setTimeout(
function(arg1){ // let's get rid of braces
return function () {
console.log(arg1); //ya arg1 has the value: 'bar'!
}
}(bar), 2000);

It works because of FunctionExpression concept. Parenthesis are only needed to differentiate FunctionExpressions from FunctionDeclaration. In fact, parenthesis could be replaced with any operator, like ~, for example.

Note: even thought this code could be written without parenthesis, I strongly object doing it, because of parenthesis now are something like a pattern or a keyword saying "Look! I'm useless bracket, probably placed here for reason like immediately invokation of this function". So code becomes a bit more clear this way.

There are plenty discussions on FunctionExpression vs FunctionDeclaration on the web, so I won't repeat once again. Take a look at past SO question: What is the difference between a function expression vs declaration in Javascript?

What is the difference between these two javascript constructs

The phrases are functionally identical, the placement of the () is something of a matter of taste and I've see directions to do either in favour of the other. Personally I prefer

(function() { ... }());

That form, creates the function and executes it inside of the parenthesis.

(function() { ... })();

Creates the function inside of the parenthesis and then executes it.

(...()) vs. (...)() in javascript closures

There's no difference. Both are valid ways to get the JavaScript parser to treat your function as an expression instead of a declaration.

Note that + and ! will also work, and are sometimes used by minifiers to save a character of size:

+function() {  
var foo = 'bar';
}();

!function() {
var foo = 'bar';
}();

EDIT

As @copy points out, for completeness, ~ and - will also work.

-function() {  
var foo = 'bar';
}();

~function() {
var foo = 'bar';
}();

How can I make var a = add(2)(3); //5 work?

You need add to be a function that takes an argument and returns a function that takes an argument that adds the argument to add and itself.

var add = function(x) {
return function(y) { return x + y; };
}

JavaScript closure using function declaration

Do closure always need to be declared using function expression and not function definition declaration

No. Any function definition will form a closure when it closes over an outer-scope variable.

It's just that usually when using a closure, we want to do a single thing with the function object so we just put it as an expression in the call or assignment or return statement instead of declaring it up-front and the referring to it by name.

Do closure need to be self invoked in function expression

No. Most IIFEs are not closures at all. They do however often provide a scope for closure definitions. Closures can be created in any kind of scopes though, even in block scopes (with let/const).

I understand key difference between function declaration and function expression is hoisting. What are the other advantages and disadvantages of using any one of them?

Have a look at var functionName = function() {} vs function functionName() {}.

Can anyone help me when and which in situation i should decide whether i should go with function declaration or function expression.

Whenever you initialise a variable declaration with a function expression, just use a function declaration instead. Otherwise, you'll mostly use function expressions.


Your example doesn't really have anything to do with the question. There is no difference between

function makeCounter() {
var count = 0;
return function increment() { return count++; }
}

and

function makeCounter() {
var count = 0;
function increment() { return count++; }
return increment;
}

except that the first a line shorter. And of course you have to do

var counter = makeCounter(); // assigns increment function to counter
counter(); // calls increment

to count anything. In your IIFE version you just inlined makeCounter as a function expression:

var counter = (function makeCounter() {
var count = 0;
return function increment() { return count++; }
// increment(); - this statement is never evaluated
})();
counter();


Related Topics



Leave a reply



Submit