(...()) 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:
- A function and
- 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 FunctionExpression
s 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
definitiondeclaration
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
Can Nokogiri Interpret JavaScript? - Web Scraping
React - User-Defined Jsx Components Not Rendering
How to Pause Setinterval() Functions
Explanation of [].Slice.Call in JavaScript
How to Run JavaScript Inside Swift Code
Sort an Array of Object by a Property (With Custom Order, Not Alphabetically)
How Should Look a Application.Scss File in Ruby
How to Preview Uploaded Image Instantly with Paperclip in Ruby on Rails
Uint8Array to String in JavaScript
What Does It Mean That JavaScript Is a Prototype Based Language
How to Get an Ajax Get-Request to Wait for the Page to Be Rendered Before Returning a Response
Console.Log() After Setstate() Doesn't Return the Updated State
Force Download an Image Using JavaScript
Push Is Overwriting Previous Data in Array
How to Set Bootstrap Navbar Active Class with Angular Js
Format a Number as 2.5K If a Thousand or More, Otherwise 900