I am a bit new to javascript, i was just trying the below snippet:
_getUniqueID = (function () {
var i = 1;
return function () {
return i++;
};
}());
s = _getUniqueID();
console.log(s); // 1
console.log(_getUniqueID()); // 2
I was under the impression that i would have to do s() to get 1 as the result and i was thinking that _getUniqueID() returns a function rather than execute the funtion inside it. Can somebody explain the exact execution of this function please ?
What you're seeing here is a combination of Javascript's notion of closure combined with the pattern of an immediately invoked function expression.
I'll try to illustrate what's happening as briefly as possible:
_getUniqueID = (function () {
var i = 1;
return function () {
return i++;
};
}()); <-- The () after the closing } invokes this function immediately.
_getUniqueID is assigned the return value of this immediately invoked function expression. What gets returned from the IIFE is a function with a closure that includes that variable i. i becomes something like a private field owned by the function that returns i++ whenever it's invoked.
s = _getUniqueID();
Here the returned function (the one with the body return i++;) gets invoked and s is assigned the return value of 1.
Hope that helps. If you're new to Javascript, you should read the book "Javascript, the Good Parts". It will explain all of this in more detail.
_getUniqueID = (function () {
var i = 1;
return function () {
return i++;
};
}());
s = _getUniqueID();
console.log(s); // 1
console.log(_getUniqueID()); // 1
when you do () it calls the function,
a- makes function recognize i as global for this function.
b- assigns function to _getUniqueID
you do s = _getUniqueID();,
a - it assigns s with return value of function in _getUniqueID that is 1 and makes i as 2
when you do _getUniqueID() again it will call the return function again
a- return 2 as the value and
b makes value of i as 3.
This is a pattern used in Javascript to encapsulate variables. The following functions equivalently:
var i = 1;
function increment() {
return i ++;
}
function getUniqueId() {
return increment();
}
But to avoid polluting the global scope with 3 names (i, increment and getUniqueId), you need to understand the following steps to refactor the above. What happens first is that the increment() function is declared locally, so it can make use of the local scope of the getUniqueId() function:
function getUniqueId() {
var i = 0;
var increment = function() {
return i ++;
};
return increment();
}
Now the increment function can be anonymized:
function getUniqueId() {
var i = 0;
return function() {
return i ++;
}();
}
Now the outer function declaration is rewritten as a local variable declaration, which, again, avoids polluting the global scope:
var getUniqueId = function() {
var i = 0;
return (function() {
return i ++;
})();
}
You need the parentheses to have the function declaration act as an inline expression the call operator (() can operate on.
As the execution order of the inner and the outer function now no longer make a difference (i.e. getting the inner generator function and calling it, or generate the number and returning that) you can rewrite the above as
var getUniqueId = (function() {
var i = 0;
return function() {
return i ++;
};
})();
The pattern is more or less modeled after Crockford's private pattern
_getUniqueID = (function () {
var i = 1;
return function () {
return i++;
};
}());
console.log(_getUniqueID()); // 1 , this surprised me initially , I was expecting a function definition to be printed or rather _getUniqueID()() to be called in this fashion for 1 to be printed
So the above snippet of code was really confusing me because I was't understanding that the above script works in the following manner, by the time the IFFE executes _getUniqueID is essentially just the following:
_getUniqueID = function () {
i = 1
return i++;
};
and hence,
_getUniqueID() // prints 1.
prints 1.
Note: please note that I understand how closures and IFFE's work.
Related
Recently while I was trying to learn more about IIFE and modules in JavaScript
a question came to my mind that how is IIFE making a Module while not Immediately
Invoking the function doesn't make it a module..
can anyone share with me the Difference between this code
var MODULE = (function () {
var my = {},
privateVariable = 1;
function privateMethod() {
// ...
}
my.moduleProperty = 1;
my.moduleMethod = function () {
// ...
};
return my;
}());
and this code where the function is not Immediately Invoked..
var MODULE = function () {
var my = {},
privateVariable = 1;
function privateMethod() {
// ...
}
my.moduleProperty = 1;
my.moduleMethod = function () {
// ...
};
return my;
};
Does the second block of code means that Module is just a function that itself returns an object?
IF I use the second variable like this
var ModuleObj = Module();
Will this work the same as the first Code block that I shared like IIFE.. Kind of confused...
Yeah you pretty much got the idea of the difference between the two, let's look at why you might want one over the other.
An IIFE is useful to isolate the scope. It lets you keep the variables you define private inside the IIFE without polluting the global space around it. It's a nice way to compose a function that has some variables you don't need lurking around. Let's minimize this example a bit.
var Counter = (function () {
var count = 0;
var counter = {
add: function () {
count++;
},
subtract: function () {
count--;
},
getCount: function () {
return count;
}
}
return counter;
})();
Counter.add();
Counter.add();
Counter.getCount(); // 2
Counter.subtract();
Counter.getCount(); // 1
What happens above is that we're able to compose this "counter" functionality without leaking the private information, like count. It'd be bad if other things could override it by accident. Also what happens is that right away we can assign Counter to the result of the IFFE -- the counter set of functions. Counter is now equal to that, and counter is able to retain access to count since it was defined in the same scope.
The benefit here is that we're able to assign a variable to this composition of functionality. The IIFE basically allows us to immediately return what we return inside of it. Since we assign Counter to the IIFE, and the IIFE returns the functionality inside of it, Counter is now a fully functional component.
We don't always have to use IIFE. It's really handy when you want to "tuck away" the implementation details and return an API.
So, what if we had the same thing, but it wasn't an IIFE -- just a function?
Just like your example, we'd have to call it in order to get the "instance".
var CounterFactory = function () {
var count = 0;
var counter = {
add: //...
subtract: //...
getCount: //...
};
return counter;
};
var CounterA = CounterFactory();
var CounterB = CounterFactory();
CounterA.add();
CounterA.add();
CounterA.getCount(); // 2
CounterB.add();
CounterB.getCount(); // 1
See the difference? It's all about what the function is returning. In the first example we only get a single Counter instance, which may be perfectly fine. In the second example, it's more of a "factory" -- it generates an instance of counter and we can call that multiple times and get multiple instances of it.
Ok an IIFE runs the functions within it and defines the variable MODULE to the return of that function. The other declares the MODULE variable to the function itself.
Think of it this way (also try it in your console to see the results).
This code does not run the console.log method.
(function(){
console.log('ran')
});
This code does
(function(){
console.log('ran')
})();
So the whole point of the IIFE is to run the function before doing anything and the (); at the end does this.
If we take the code that did not run and assign it to a value what happens?
var foo = (function(){
console.log('ran')
});
foo();
We have a function foo that we can execute.
So what is the point of an IIFE if we can just assign it and run it later? The answer to that is local variables which you can use for closure later.
console.log(num); //get undefined
(function(){
var num = 'ran';
console.log(num) //get 'ran'
})();
console.log(num); //get undefined
We get undefined ran then undefined so the values we declare in the function stay in the function and nothing else can get to them. This is the lexical scoping that JavaScript runs off of.
Just for fun lets do a closure with it.
var add = (function(){
var num = 0;
return function(){
console.log(num++);
}
})();
console.log(num) //get undefined
add() //get 1
add() //get 2
console.log(num) //still undefined
Let's say I have this JavaScript closure:
var add = (function () {
var counter = 0;
return function () {return counter += 1;}
})();
and I call add three times:
add();
add();
add();
Now the counter in the self-invoking function is equal to 3. But why will the above not increment counter or keep the parent function's scope alive if the self-invoking function was instead a predefined or even an anonymous function?
By predefined function i mean standard function declaration,something like this:
function testingjsclosure()
{
var counter = 0;
return function(){return counter += 1;}
}
add = testingjsclosure();
There is no self-invoking function here.
The expression
function () { var counter = 0; return ...; }
has as value a function that has local state and returns a certain value. So
var add = (function () { var counter = 0; return ...; })();
calls it and assigns the returned value to add. That value is
function () {return counter += 1;}
which is a function that increments and returns that particular local variable. So calling add calls that function and so increments and returns that particular local variable.
But
add = testingjsclosure();
calls testingjsclosure with no arguments and assigns its return value to add.
function(){ ... } is like quote marks around an expression ... in that that expression is not evaluated until the variable that has the value of the function expression is called.
Whereas
function testingjsclosure() { ...}
is like writing
var testingjsclosure = function() { ...}
This question already has answers here:
What is the (function() { } )() construct in JavaScript?
(28 answers)
Closed 9 years ago.
I got so confused here. Can someone help me peel the layers off the function definition here? What are the out-most parentheses for? Why argument (p) can be after }, and which function is it for? Where is q required at all? Why can p directly call publish() later?
var p = {};
(function(q) {
q.publish = function(topic, data){
...
};
}(p));
...
p.publish("inbox", "hello");
It simply creates the function and executes it immediately.
For example:
var foo = function() {
return 5;
}();
console.log(foo);
will print 5.
If you want to learn more about it, please read this excellent article http://benalman.com/news/2010/11/immediately-invoked-function-expression/
I would like to quote module pattern example from the link I shared.
var counter = (function(){
var i = 0;
return {
get: function(){
return i;
},
set: function( val ){
i = val;
},
increment: function() {
return ++i;
}
};
}());
console.log(counter.get());
counter.set(3);
console.log(counter.increment());
console.log(counter.i);
Output
0
4
undefined
Here we are dynamically creating an Object at the same time we are making i private. This is called closure property.
Putting the function in parentheses means the JS interpreter takes it as a function expression, so it can be anonymous (i.e., not have a declared name). Adding () at the end means the function is called immediately. So, e.g.:
(function() {
alert('Hi');
}());
...declares a really simple function with no arguments, and calls it immediately. A slightly more complicated one with an argument might look like this:
(function(someArgument) {
alert(someArgument);
}('Hi'));
That would alert 'Hi', because the string 'Hi' is passed to the anonymous function when it is called.
So with that as background, here's what your code is doing line by line:
var p = {}; // declare variable p, referencing an empty object
(function(q) { // make an anonymous function expression that takes one argument, q
q.publish = function(topic, data){ // add a property 'publish' to whatever q is,
... // where 'publish' is a function that takes
}; // two arguments
}(p)); // call the anonymous function, passing p in
...
p.publish("inbox", "hello"); // call the method 'publish' that was added to p
The q argument that you asked about takes the value from p, so it refers to the same empty object, but then it adds the .publish() method to that object.
This general concept is called an "Immediated invoked function expression", or IIFE.
Usually if an IIFE is just sitting there by itself like that (i.e., another variable is not assigned equal to it) it is done so that working variables/functions can be created temporarily without adding them to the global scope, because in JavaScript the scope options are basically global or function. The code you show doesn't do that, but here's a simple example:
(function() {
var x = 0;
for (var i = 0; i < 100; i++)
x += i;
alert (x);
}());
// here x and i are not accessible because they're local to the function above.
It's a self executing function. Using q is useless here since q === p.
var p = 'hello';
function f(q){ return q; }; f(p); // "hello"
(function(q){ return q; }(p)); // "hello"
(function(){ return p; }()); // "hello"
/*(*/function(){ return p; }()/*)*/; // SyntaxError: Unexpected token (
This pattern is usually used to create a private context for variables. Here is a well known example :
var counter = function(){
var i = 0;
return function(){
return ++i;
};
}();
counter(); // 1
counter(); // 2
i; // undefined
Have a look at this great article : http://www.adequatelygood.com/JavaScript-Scoping-and-Hoisting.html.
Reading an example from a book, can someone explain how the function call to fibonacci takes in the argument 'i' when the function itself doesn't declare any parameters?
var fibonacci = (function () {
var memo = [0, 1];
var fib = function (n) {
var result = memo[n];
if (typeof result !== 'number') {
result = fib(n - 1) + fib(n - 2);
memo[n] = result;
}
return result;
};
return fib;
}());
for(var i = 0; i <= 10; i += 1) {
document.writeln('// ' + i + ': ' + fibonacci(i));
}
You are creating a self-executing anonymous function (function(){}()); which inside it returns the fib function, which takes an argument. var fib = function(n){} ... return fib;
var fibonacci = (function () { // Self-executing anonymous function
var memo = [0, 1]; // local variable within anonymous function
var fib = function (n) { // actual fib function (takes one argument)
var result = memo[n];
if (typeof result !== 'number') {
result = fib(n - 1) + fib(n - 2);
memo[n] = result;
}
return result;
};
return fib; // return fib (fibonacci is now set to the function fib defined above, which takes one argument)
}());
This system (returning a function from a self-executing anonymous function) allows for you to define variable in a local scope that can still be used by the returned function, but not by functions outside the scope. Here is an example.
This technique is called closure in JavaScript. Read more about it on the MDN guide.
Because the function returns a function that does take a parameter.
To understand this, I think it is helpful to work with a simpler example. Take a look at the two memoized functions below. The only difference is the () after add : function (){ ... }() on the successful memorization code.
var failed_memoization = {
add : function (){
var counter;
return function(number){
if(counter){
counter = counter + number;
return counter;
}
counter = number;
return counter;
} //NOTE: NO function call brackets here
}
}
var successful_memoization = {
add : function (){
var counter;
return function(number){
if(counter){
counter = counter + number;
return counter;
}
counter = number;
return counter;
}
}() //NOTE: the function call brackets here!!
};
}
Now let's execute these two functions.
console.log('Failed Memoization');
console.log(failed_memoization.add(5)); //We wanted 5, but this prints the text of the function instead.... Okay, lets try something else
console.log(failed_memoization.add()(5)); //5
console.log(failed_memoization.add()(10)); //10 (Wanted it to be 5+10 = 15.
console.log('successful_memoization');
console.log(successful_memoization.add(8)); //8
console.log(successful_memoization.add(16)); //24 (This is what we wanted 8 + 16 = 24)
So what's going on here is that for successful_memoization when we put () to the end of its add : function(){...}(). As such, this function is executed immediately on the creation of the static object. In turn, executing that function returns the object function (number){...} wich results in the assignment: add : function (number){...} NOT add : function(){} as it initially appears.
What is also important to note is that var counter is declared outside return function(name){}. As it is still being used within add : function(number){...}, this variable is accessible within that function. For failed_memoization.add()(number), it uses a new counter each time we execute that function, because we execute the first function, and then the inner function on each call. For successful_memoization.add(number) we executed the outer function upon initialization, and so counter will persist through all subsequent calls and will not be overwritten.
There is a self-calling function that returns the function with the identifier fib which is then assigned to the identifier fibonacci. This way you can create a private variable memo which is only accessible by the function. So var fibonacci in fact is function(n){...}.
var fibonacci = (function() {
...
return fib;
})();
This is a self-executing function.
It declares a function expression which returns a function (fib), executes the outer function expression immediately (()), and assigns its return value (which is fib) to the fibonacci variable.
Function fibonacci does take one argument. Note that the unnamed function that starts on the first line is not the function that ends up being known as fibonacci. That unnamed function is immediately called since you have () immediately after closing brace }. This unnamed function returns fib, a local variable to which a single-argument function is assigned. Thus, fibonacci ends up referring to the function returned by the unnamed function, i.e. fibonacci is this:
var fib = function (n) {
var result = memo[n];
if (typeof result !== 'number') {
result = fib(n - 1) + fib(n - 2);
memo[n] = result;
}
return result;
};
Note that this function refers to local variables of the unnamed function for the purpose of memoizing.
The critical thing to notice was () which calls the unnamed function immediately, here are some examples that illustrate this technique:
var a = (function() { return 1; });
Variable a holds a function which returns 1.
var a = (function() { return 1; }());
Here however, variable a holds value 1.
I want to build a javascript function that maintains state. Here's a pattern that I've come up with, but something in the back of my mind tells me this is an anti-pattern.
function f() {
var state = 1;
f = function() {
return state++;
};
return f();
};
Is there anything wrong with this? If so, what's a better approach?
Well it's a matter of opinion what the best way is, but (although I know it works) I'm a little uncomfortable with having the function overwrite itself. A similar pattern that doesn't do that but still uses practically the same closure idea is this:
var f = function() {
var state = 1;
return function() {
return state++;
};
}();
Or here is another way:
function f() {
return f.state++;
}
f.state = 1;
Of course with the f.state method the advantage and disadvantage (depending on your needs) is that the .state property can be read and modified by other code.
Normally, you set a closure scope and return a function that has access to that scope. Every time that function is now called, the state will remain as long as that function exists. Example:
var statefulFunction = function() {
// set up closure scope
var state = 1;
// return function with access to the closure scope
return function() {
return state++;
};
}(); // immediately execute to return function with access to closure scope
var first = statefulFunction(); // first === 1
var second = statefulFunction(); // second === 2
Another pattern is to create a closure scope and return an object with methods that have access to that closure scope. Example:
var myStatefulObj = function() {
// set up closure scope
var state = 1;
// return object with methods to manipulate closure scope
return {
incr: function() {
state++;
},
decr: function() {
state--;
},
get: function() {
return state;
}
};
}();
myStatefulObj.incr();
var currState = myStatefulObj.get(); // currState === 2
myStatefulObj.decr();
currState = myStatefulObj.get(); // currState === 1
A better way to achieve this might be to use an Immediately-Invoked Function Expression (IIFE) to encapsulate your state.
var f = (function () {
var state = 1;
return function() {
return state++;
};
}());
console.log(f()); // 1
console.log(f()); // 2