Does closure always needs be in IIFE? - javascript

Any function within function forms a closure. Do closures always needs to be in an immediately invoked function?
The first example is where a closure is formed within an iife and works as expected, gives "8" and "7" as output.
var cat = (function (){
var lives = 9;
return function() {
return --lives;
}
}());
console.log("iife");
console.log(cat());
console.log(cat());
In the below example the closure does not work as expected, prints the same value every time.
var cat = function (){
var lives = 9;
return function() {
return --lives;
}
};
console.log("no iife");
console.log(cat()());
console.log(cat()());

A closure is just the link between a function and the scope in which it was created, link which exists when the function uses a variable from this scope.
You have this problem because you don't keep the closure: you're recreating it at every console.log when you call cat().
Change
console.log(cat()());
console.log(cat()());
into
let c = cat();
console.log(c());
console.log(c());

Related

In a closure, why does the main variable not get reset every time it is called?

I'm trying to get a solid understanding of closures, and I'm struggling with the mechanics of it. I've looked on w3schools (https://www.w3schools.com/js/js_function_closures.asp) and MDN (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures) and a few other places. I understand what a closure is and how to make it work but I don't understand why subsequent calls after the first call to the outer function just seem to go straight to the inner one instead.
Here is my code - a simple, working closure:
var add = (function () {
var a = 0;
alert('hi');
function addInner(){
a += 1;
return a;
}
return addInner;
})();
function getAdd() {
document.getElementById("test").innerHTML = add();
}
I have two questions that probably both have the same answer: Why does a not get reset every time I call add()? And why does the alert not pop up except for on the first time?
I attached getAdd() to a button, and it works great, but it but doesn't pop up with the alert past the first time. Why does it do this?
Edit: I also found the first answer to this question (Why Don't Variables Reset in a Closure (Javascript)) really helpful.
add is a reference to addInner, not the anonymous "outer" function, since the "outer" function returns addInner. Then, you call that anonymous function once - that last set of ()- and store the resulting function, with its own private 'a', in add.
Imagine that the outer function was a named function called constructAdder, and you called
var add = constructAdder();
var add2 = constructAdder();
That's basically what you've done, but with an anonymous function, if that makes it any clearer. You have an outer function that constructs an inner function that can count, due to the magic of closures.
Those questions do both have the same answer. And it's fairly simple. This statement:
var val = (function() {
return 42
}())
sets val to 42. Not a function. This is called an IIFE, or immediately-invoked function expression. We are declaring a function and calling it immediately. We never save that function. We just use it once to get the value it returns:
val // 42
Contrast that to:
var val = function() {
return 42
}
In this case we set val to a function that, when called, returns 42.
val() // 42
val() // 42
We can get pretty crazy with IIFEs:
var val = (function() {
return (function() {
return (function() {
return 42
}())
}())
}())
The value returned by that mess is still 42.
val // 42
All those functions are declared once, used once, and thrown away. But IIFEs are capable of so much more:
var add = (function() {
var counter = 0
return function() {
return counter++
}
}())
We're now using the IIFE to create a private variable! counter cannot be accessed outside the scope of the IIFE. It's safe. But the inner function can access and modify it. It's a fully encapsulated, stateful function!
add() // 0
add() // 1
counter // Uncaught ReferenceError: counter is not defined
This is what your code is doing:
var add = (function () {
var a = 0;
alert('hi');
function addInner(){
a += 1;
return a;
}
return addInner;
})();
It is encapsulating the a variable so that it cannot be accessed outside the scope of the IIFE. The addInner function, however, does have access to a and can modify it at will.
The alert() is only called once because that IIFE is only called once, then thrown away. Note that the function itself is the only thing thrown away. Since addInner maintains a reference to the scope (closure) created by the IIFE, that scope is safe from garbage collection.
In fact, that's a helpful way to think about IIFEs:
var val = function() {}
creates a function and
val()
creates a closure (the context that the function's body runs in). IIFEs are used when we don't care about the function, we just want the closure it creates.
Hope this helps. Have fun out there!
var add = (function () {
var a = 0;
alert('hi');
function addInner(){
a += 1;
return a;
}
return addInner;
})(); <-- This
The () at the end means that add is added forever, and if you look at the line above, then it says return addInner. This means that add() is actually addInner(), the good thing with this is that addInner has access to a. Actually writing the function like this is more proper.
var add = (function () {
this.a = 0;
alert('hi');
var addInner = function(){
this.a += 1;
return this.a;
}.bind(this);
return addInner;
})();
Because now you would think that add.a would make a available because it is written as this.a, but since addInner is returned, then it is not available.
You should focus on the
(function(){
// impl
})()
block.
It is called an Immediately Invoked Function Expression or IIFE.MDN reference
So when the code executes to line 1, it first evaluate the right side and the IIFE returns a closure which was then assigned to the variable add. Meanwhile, an alert was invoked in the IIFE. Understanding the IIFE can help you solve the problems.
In my opinion , the key is IIFE, after the code below is executed at the first time,
var add = (function () {
var a = 0;
alert('hi');
function addInner(){
a += 1;
return a;
}
return addInner;
})();
(Look out ! There is no add() in the code above because IIFE will be Invoked Immediately and the return addInner finished the initialization of variable add )
the function add has been changed to :
add = function addInner() {
a += 1;
return a;
}
Of course, the alert() only executed one time because the add has been changed at the begining.
Why does a not get reset every time I call add()?
And why does the alert not pop up except for on the first time?
that is the answer of your question.
variable a didn't destroy because the function add still have a reference, and this is about the closure.

Does the callback function create a new scope in javascript

function hello() {
var result = [];
var str = 'I am here';
function inner() {
var result = [];
for (var i=0;i<10;i++) {
result.push(i);
}
return result;
}
}
in the code above when I called the function hello(), the return value was an empty [], also it did not console.log the str from the inner function. However, in the below code set I have used a call back function:
function forEach(cb) {
for(var i =0;i<10;i++) {
cb(i);
}
}
function hello() {
var result = [];
var str = 'I am here';
forEach(function(num) {
console.log(str);
result.push(num);
});
return result;
}
the question is why both functions reacted, and gave a different output? Note; in both codes there was an inner function which supposed to create a new scope that can access the outer scope ? Does anyone have a good explanation for this issue ?
Thanks
In the first code block, inner is a new function that is declared inside of hello. It does not execute because you do not call it. It does create a new child scope inside of hello when it is called. But, since hello() doesn't actually return anything and doesn't call inner(), you get undefined when you call hello(). You could fix that by changing to this (you can run this snippet to see the return value):
function hello() {
var str = 'I am here';
// declare inner
function inner() {
var result = [];
for (var i = 0; i < 10; i++) {
result.push(i);
}
return result;
}
// now call inner() and return its result
return inner();
}
console.log(hello());
Functions declared inside other functions do create a new scope. Every function declaration and corresponding call in Javascript creates a new scope. If the function is inside another function, then the code inside that inner function has access to both its local scope and to the parent scope and this can nest as deep as your nested function declarations go.
the question is why both functions reacted, and gave a different
output? Note; in both codes there was an inner function which supposed
to create a new scope that can access the outer scope ? Does anyone
have a good explanation for this issue ? Thanks
In the first example, you never called the inner function so it never executed.
In the second example, you pass an inline, anonymous function reference as a function argument to your forEach() function. When that forEach() function executes, it calls your callback function with the line of code cb(i) so that's how your callback function is getting called in the second example. forEach() calls it for you.
Also, in the second example, the locally declared callback function is accessing the parent scope and modifying the result array (which is perfectly allowable). In your first code example, you are declared a new result variable in the inner function scope and then returning that. You are not accessing the parent result variable. When you declare a local variable with the same name as a variable in the parent scope, the local variable overrides the parent variable (essentially hiding the parent variable) and any references to that variable in the local scope only access the local variable.
You could have written the first code example to use a parent scoped result variable like this:
function hello() {
var result = [];
var str = 'I am here';
// declare inner
function inner() {
for (var i = 0; i < 10; i++) {
result.push(i);
}
return result;
}
// now call inner() and return result
inner();
return result;
}
console.log(hello());
You have confused function declaration and calling.
Declaring a function can be done in multiple ways:
function myNewFunction() {}
Now this function exists in the current scope, but will not execute unless called.
You can call the function like this. Now your function will get executed.
myNewFunction();
Functions and their scopes can be compared to variables. Functions defined inside another function can only be accessed from inside the parent function. Let me give you an example.
function myMegaFunction() {
console.log("in mega");
function mySmallFunction() {
console.log("in small");
}
}
myMegaFunction();
This will only print - 'in mega'. If you call mySmallFunction() inside of myMegaFunction then both lines will get printed.
Now let's take a more complex scenario like this:
function myMegaFunction() {
console.log("in mega");
var str = "car";
var result = function mySmallFunction() {
console.log("in a small", str);
}
return result;
}
var resultingFunction = myMegaFunction();
resultingFunction();
This will first print the following:
in mega
in a small car
So essentially, this is functions being passed around like variables. They can be executed later on too.

Difference between an IIFE and non-IIFE in JavaScript Modular approach

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

Execution order of simple function

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.

Output of this javascript and the reason

function getCtr(){
var i = 0;
return function(){
console.log(++i);
}
}
var ctr = getCtr();
ctr();
ctr();
I've been using Javascript from last five years, but this question made me dumb in last interview. I tried everything to my knowledge but can't figure it out.
Can you please help me with the output and reason for it so that I can be better equipped for future interviews if I have one.
var ctr = getCtr();
This calls getCtr(), which initializes i to 0, and stores a reference to the function
function() {
console.log(++i)
}
in ctr. Because that function was created in the scope of getCtr(), the variable i is still accessible in the scope of the function stored in ctr.
The first call to
ctr()
executes console.log(++i) which has a preincrement on i, so it prints out 1. The second call executes the same code, with the same preincrement, and prints out 2.
DISCLAIMER: Not a javascript developer. Forgive me if I've made an error or used some unpreferred wording.
So the code you posted outputs 1 2. Yet the code:
function getCtr(){
var i = 0;
return function(){
console.log(++i);
}
}
getCtr()();
getCtr()();
outputs only 1 1!
The difference is that if you save a reference to getCtr() by using the var ctr = getCtr();, you create what is called a closure.
So the difference between calling getCtr()() and ctr() is that ctr has i defined in its scope, and that scope is saved thanks to var ctr = getCtr();. Because the reference is saved, the function inside of ctr is able to always act on the same variable.
run this:
var m=0;
var d=0;
alert(m++ +":"+ ++d);
and you get "0:1"
IF it were me asking in an interview, the difference in where the ++ is is what I would be after :)
http://jsfiddle.net/MarkSchultheiss/S5nJk/
Closures
The return statement in that function saves i. So when var i = 0; is only called var ctr = getCtr();. Then ctr becomes the returned function:
function () {
console.log(++i)
}
and the variable ctr has i in the scope of the outer function, getCtr() and the return function is in the scope of getCtr() as well.
okay, getCtr is a function that returns an other function.
It also contains a var called "i" which is set to 0.
"i" is also available in the scope of the returned function.
the preincrement of "i" before logging it to the console causes that it increases by 1 every time the returned function, which is stored in "ctr", is called.
When executed, function getCtr returns an inner anonymous function.
This function is now referenced by variable ctr
Because the anonymous function was created inside getCtr it will have access to getCtr private scope object, which contains variable 'i'. This is known as a closure.
var ctr = getCtr()
Every time the anonymous function is executed it pre-increments i, and writes in in the console.
ctr()
Lets break it down using terms you might know from classical inheritance based OOP languages:
// In javascript functions are first-class objects
// This function is being used like a class would be in Java
function getCtr(){
// You can think of this as a private variable of the getCtr "class"
var i = 0;
// Because it is returned, this is effectively a public method of getCtr
return function(){
// Which increments i and then prints it.
console.log(++i);
}
}
// This makes the variable ctrl an instance of getCtr.
var ctr = getCtr();
// This calls ctr's only public method.
ctr();
ctr();
So the output would be "1, 2".
What this question is meant to do is test if you understand Javascript's prototypal inheritance, ability to have anonymous functions, and closures.
A clarified version of that could that would do the same thing would be:
var myProtoype = function() {
var privateVariable = 0;
var privateMethod = function () {
privateVariable++;
console.log(privateVariable);
}
return {
publicMethod: privateMethod
};
}
var myInstance = new myPrototype();
myInstance.publicMethod();
myInstance.publicMethod();
That function is a Javascript Module. You can have a good reading about it on Javascript: the Good Parts, which is a great book and I highly recommend. A Module uses Javascript closures to create private variables and if assigned to a var the var will retain it's vars each time it's called instead of redefining the vars.
A module works like this
function moduleName(privateVar1){
var privateVar1;
var privateVar2;
return {
exposedFunction1: function (var1) {
// Do stuff... using private vars
return something;
},
exposedFunction2: function (var1, var2) {
// Do stuff...
return something;
}
}
}
var moduleInstance = moduleName(privateVar1);
moduleInstance.exposedFunction(var1);

Categories