I don't quite understand this bit of code.
$('div').click((function () {
var number = 0;
return function () {
alert(++number);
};
})());
My understanding is:
An anonymous function is defined and assigned to the click handler.
When I click on div, this function is invoked.
What the function does is:
Define a variable number = 0
Return ++number
So why does the number in alert increment every time I click? Shouldn't number be reset to 0 every time I click?
Here you've got a self-invoking function, which returns a function. Watch out for the brackets at the end:
(function () {
var number = 0;
return function () {
alert(++number);
};
})()
So the callback of the click handler is only the returned inner function:
function () {
alert(++number);
};
This inner function has access to the variable number, which is in the scope of the outer function.
So your code can also be written as follows:
function outerFunction() {
var number = 0;
return function () {
alert(++number);
};
};
var innerFunction = outerFunction();
$('div').click(innerFunction);
If we used (ugly) names for the anonymous functions, your code could be rewritten as:
$('div').click((function makeIncrementer() {
var number = 0;
return function incrementAndAlert() {
alert(++number);
};
})());
More verbose code retaining similar semantics would be:
var makeIncrementer = function() {
var number = 0;
return function() { alert(++number); };
};
var incrementAndAlert = makeIncrementer(); // function() { alert(++number); }
$('div').click(incrementAndAlert);
makeIncrementer is a function that, when called, defines a number variable in its scope, and returns a function - note that makeIncrementer doesn't increment, nor alert the number variable, instead it returns another function that does just that.
Now incrementAndAlert is bound to this returned function
function() { alert(++number); }
that captures makeIncrementer's number variable, which enables it to keep number's state between incrementAndAlert calls triggered by $('div') clicks.
This is not an "answer", but hopefully it will show a different way of looking at the problem.
First off, note that JavaScript functions are just objects and are thus just values that can be bound to variables. As such,
$('div').click((function () {
var number = 0;
return function () {
alert(++number);
};
})());
can be, with a simple expression substitution, rewritten as
var f = function () {
var number = 0;
return function () {
alert(++number);
};
};
// $('div').click((f)()); and when removing extra parenthesis ->
$('div').click(f());
Then, after one more simple expression substitution
var g = f()
$('div').click(g);
it should be clear that the (outer) function, f, is invoked first and it is the resulting (inner function) value, g, that is used as the handler.
Aside from introducing variables, the above substitutions are semantically equivalent to the original code.
Related
I want to understand the way anonymous self invoking function is able to maintain the last updated state of variable but why is it not possible in case of normal anonymous functions .Both functions are closures
still are behaving differently while maintaining the previous state of variable.
ex:
var selfInvokingfunc= (function () {
var a=2;
var myprivatefunction = function () {
a=a+2;
console.log(a);
}
return {
mypublicfunction : function () {
myprivatefunction();
}
}
})();
selfInvokingfunc.mypublicfunction() ;//a is 4
selfInvokingfunc.mypublicfunction(); // a is 6
var nonSelfInvokingAnonymousFunction = function () {
var a=2;
var myprivatefunction = function () {
a=a+2;
console.log(a);
}
return {
mypublicfunction : function () {
myprivatefunction();
}
}
};
nonSelfInvokingAnonymousFunction().mypublicfunction(); //a is 2
nonSelfInvokingAnonymousFunction().mypublicfunction(); //a is 2
Same works fine for non self invoking if invoked as :
var temp=nonSelfInvokingAnonymousFunction();
temp.mypublicfunction() ; // a is 4
temp.mypublicfunction(); // a is 6
Please help me understand the same.
Every time the main body of the outer function is executed and the lines:
var a=2;
var myprivatefunction = function () {
// ...
are run, a new binding for those variables are created in memory.
With the self-invoking function, since it's executed immediately and once, there then exists one binding for the a variable, which the mypublicfunction property can see via the closure.
In contrast, with your nonSelfInvokingAnonymousFunction, every time you invoke it, you create a separate binding for a:
nonSelfInvokingAnonymousFunction().mypublicfunction(); //a is 2
// ^^^ creates an a ^^^^
nonSelfInvokingAnonymousFunction().mypublicfunction(); //a is 2
// ^^^ creates a SEPARATE a ^^^^
When you have two separate bindings for the a variable, calling mypublicfunction on a function that closes over one of the bindings will have no effect on the other binding.
In your last code, when you do
var temp = nonSelfInvokingAnonymousFunction();
// ^^^ creates an a ^^^^
temp.mypublicfunction() ; // a is 4
temp.mypublicfunction(); // a is 6
You create a single a, and a temp whose mypublicfunction function closes over that one a, so calling mypublicfunction multiple times results in that a changing multiple times.
Both of the following snippets print "arrow". I would like to know why. Do arrow functions have a sort of higher priority than the normal functions if they both have the same name?
function increment(){
alert("normal")
}
var increment = () => {
alert("arrow")
}
increment(); //prints arrow
var increment = () => {
alert("arrow")
}
function increment(){
alert("normal")
}
increment(); //prints arrow
This has nothing to do with arrow functions. Rather, regular functions (and var declarations) are hoisted; regardless of where you write them, they are moved to the top of their scope. Effectively, both code samples are completely identical, and they look like this:
var increment; // hoisted
function increment() { // hoisted
alert("normal")
}
increment = () => { // the assignment itself is unaffected
alert("arrow")
}
increment(); //prints arrow
The assignment portion of var increment = ... occur after the hoisted function and var declaration, in both cases. Regardless of where you actually wrote the function increment() { } declaration, it is hoisted above the line performing assignment to the increment variable.
This is why the following code still works, despite the function apparently being defined after it is used:
increment(); //prints normal
function increment(){
console.log("normal")
}
If you want to compare like with like, you need to compare var increment = () => { ... } with var increment = function () { ... }, that is, two assignments. The results look like this:
var increment = () => { console.log('arrow'); }
var increment = function () { console.log('normal'); }
increment(); # normal
vs
var increment = function () { console.log('normal'); }
var increment = () => { console.log('arrow'); }
increment(); # arrow
In both cases there is a single hoisted var increment; declaration, and then the assignments occur in the order in which they're written, meaning the last assignment wins.
As an aside, this is one of the chief reasons to prefer let x = () => { } over "old" style function declarations. let is not hoisted, so the function exists from the point in time you would naturally expect it to, instead of jumping to the top of your scope.
I have the code below:
//anonymous function expression
var a = function() {
return 3;
}
//named function expression
var a = function bar() {
return 3;
}
So, what is the different between them ? (technical, usage)
The main differences are
You can inspect the function name (for example stack traces are more readable)
The function can be recursive
Note that a function like
var fibo = function(n) {
return n<2 ? 1 : fibo(n-1) + fibo(n-2);
};
is not really recursive as its body will call whatever fibo is bound to at the moment of the call (so it will not call itself if fibo is later assigned to something else). The version
var f = function fibo(n) {
return n<2 ? 1 : fibo(n-1) + fibo(n-2);
};
is instead really recursive and will keep calling itself no matter what f is later bound to.
I have a problem getting the value of 'name' displayed with the following:
for (var name in array) {
var hoverIn = function() {
alert(name);
};
var hoverOut = function() {
};
thing.hover(hoverIn, hoverOut);
}
What I get is an alert window with the last value of name. Clearly I am doing something wrong and I suspect it's a simple fix. Can anyone help?
Thanks.
It's closure problem, name, after that iteration is the last name in array, and callback for hovers isn't executed right away when the iteration happens, thus when the hover function is actually executed, name will always be the last in array.
You need to use IEFE (Immediately executed function expression):
for (var name in array) {
// pass in name to the anonymous function, and immediately
// executes it to retain name when the particular iteration happens
var hoverIn = (function(name) {
return function() {
alert(name);
}
})(name); // if you notice, the pattern is (function(name) {})(name)
// the first () creates an anonymous function, the (name)
// executes it, effectively passing name to the anon fn
var hoverOut = (function(name) {
// same pattern if you need to re-use name inside here, otherwise just
// function() { } should suffice
})(name);
thing.hover(hoverIn, hoverOut);
}
To avoid duplicates of (function() { })() (which honestly is getting tiring to look at), you could also, as #pimvdb pointed out, wrap the whole body in a closure:
for (var name in array) {
(function(name) {
var hoverIn = function() {
alert(name);
}
var hoverOut = function() {
}
thing.hover(hoverIn, hoverOut);
})(name); // closure of for loop body
}
Add a variable inside the loop
var thisName = name;
and then use that in your function
alert(thisName);
You have two ways of dealing with this problem.
The first thing to know is that scope only happens at function level, not within loops in javascript.
If you set a variable within a function from an outside source and don't execute it right away,the variable will be changed over the course of your loop.
You can solve this by closing other the variable:
var names = ["john","paul","george","ringo"];
var store = {};
//this function receives the data as a parameter
//so it will be a safe copy.
function createFunc(name){
//just return a function that will alert the name.
return function(){
alert(name);
}
}
for (var i in names) {
var hoverIn = createFunc(names[i]);
store[names[i]]=hoverIn;
}
store["john"]();
The other way is to create an anonymous function that executes right away
within the loop:
var names = ["john","paul","george","ringo"];
var store = {};
for (var i in names) {
//the function receives the i as a parameter
//and executes, so n is a safe copy of i
(function(n){
var hoverIn = function(){
alert(names[n]);
}
store[names[n]]=hoverIn;
})(i);
}
store["john"]();
Everything is a problem related to closure.
Look at wikipedia for more info.
You should create closure:
for (var name in array) {
var hoverIn = (function() {
return function() {
alert(name);
};
}());
var hoverOut = function() {
};
thing.hover(hoverIn, hoverOut);
}
I have come across this javascript code.
var digit_name = function() {
var names = ['zero', 'one','two'];
return function(n) {
return names[n];
};
}();
alert(digit_name(1));
The output is one. I understand that the inner function is being assigned to the variable digit_name. What is the need for adding parentheses in the 6th line after the code of outer function. Can anyone tell what exactly is going on?
The added parentheses makes the outer function execute, if you omit it it will assign outer function to your digit_name instead of the inner function.
The ending () you see make that outer function execute immediately. So digit_name ends up storing the resulting inner function, as opposed to a pointer to the outer function.
For more information see: What is the purpose of a self executing function in javascript?
Let's give some names to these functions to better understand what's going on:
var digit_name = function outer() {
var names = ['zero', 'one','two'];
return function inner(n) {
return names[n];
};
}();
alert(digit_name(1));
So, there are two functions at play here: inner and outer. You're defining a function called outer, whose purpose is to create a closure scope capturing the names array, and defining and returning another function that has access to this closure. The parentheses at line 6 mean call the function, so the value that gets assigned to the digit_names variable isn't the outer function, but the inner one.
var digit_name = function() {...}; => digit_name is a function
var digit_name = function() {...}(); => digit_name is an object returned by the function
var digit_name = function() { // Create outer function
var names = ['zero', 'one','two']; // Define names array, this is done when the outer function is ran
return function(n) { // Return the new inner function, which gets assigned to digit_name
return names[n];
};
}(); // Execute the outer function once, so that the return value (the inner function) gets assigned to digit_name
There are two very quick processes here.
If we were to write this:
function makeDigitReader () { var names; return function (n) { return names[n]; }; }
var myDigitReader = makeDigitReader();
You would correctly guess that myDigitReader would be given the inner function.
What they're doing is skipping a step.
By adding the parentheses, what they're doing is firing the function the instant that it's defined.
So you're getting this happening:
var myDigitReader = function () {
var names = [...];
return function (n) { return names[n]; };
};
myDigitReader = myDigitReader();
See what's happened?
You've returned the inner function as the new value to what used to be the outer function.
So the outer function doesn't exist anymore, but the inner function still has access to the names array.
You can return an object instead of a function, as well.
And those object properties/functions would have access to what was initially inside of the function, as well.
Normally, you will either see these immediately-invoking functions wrapped in parentheses var myClosure = (function() { return {}; }());.
If you intend to run one without assigning its return to a value, then you need to put it in parentheses, or add some sort of operand to the front of it, to make the compiler evaluate it.
!function () { doStuffImmediately(); }(); // does stuff right away
function () { doStuffImmediately(); }(); // ***ERROR*** it's an unnamed function
Hope that answers all of the questions you might have.