variable calling function and calling function directly - javascript

I'm learning JavaScript with Manning's book, Get Programming with JavaScript (by John Larsen). In chapter 11, Listing 11.8, the code:
var getCounter = function () {
var counter = 0;
var countUpBy1 = function () {
counter = counter + 1;
return counter;
};
return countUpBy1;
};
var count = getCounter();
And I'm using jsbin.com to experiment and learn. In the console:
Q1) why calling count(), the result is not always 1? Why is it, counter is set to 0 at the start, before countUpBy1, shouldn't counter inside countUpBy1 also be 0?
Q2) why calling getCounter() is different from count()? calling count() get me a number (which is what I expect), but calling getCounter() get me:
function () {
counter = counter + 1;
return counter;
}
Thanks for explaining in advance.
4/Nov:
#DavidFleeman: Am I correct in my understand to first question (I read all 3 links, plus JavaScript Closures 101: What is a closure?, I never understood JavaScript closures & JavaScript Closures Explained by Mailing a Package:
(deleted my understanding of stepping through the closure)
12/Nov:
I never understood JavaScript closures
Read this link few more times, and it explained way better than I can.

Why is calling count() not always equal to 1?
These nested methods create a closure where the initialization only happens once, and the nested internal method is returned each time. Please read this link to understand:
https://www.w3schools.com/js/js_function_closures.asp
If you prefer MDN, use below link. However, the above link has example that I believe matches the member's scenario:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures
And for even more detail, this seems to be a well thought out explanation:
https://blogs.msdn.microsoft.com/ericlippert/2003/09/17/what-are-closures/
Why does getCounter() return the function object instead of executing the method?
Reading the same link above, you can see how to define getCounter() to do exactly what you are asking it to do. You must define it as a self-invoking function. In your example, it is not defined using the self invoking syntax. See example below if you want to define it to work using getCounter() instead of count().
var getCounter = (function () {
var counter = 0;
var countUpBy1 = function () {
counter = counter + 1;
return counter;
};
return countUpBy1;
})();
getCounter();

Related

Javascript hover event and local variable [duplicate]

Closures in a loop are causing me problems. I think I have to make another function that returns a function to solve the problem, but I can't get it to work with my jQuery code.
Here is the basic problem in a simplified form:
function foo(val) {
alert(val);
}
for (var i = 0; i < 3; i++) {
$('#button'+i).click(function(){
foo(i);
});
}
Naturally clicking on any of the three buttons will give an alert saying 3. The functionality I want is that clicking on button 1 will give an alert saying 1, button 2 will say 2 etc.
How can I make it do that?
See the bind method.
$('#button'+i).bind('click', {button: i}, function(event) {
foo(event.data.button);
});
From the docs:
The optional eventData parameter is
not commonly used. When provided, this
argument allows us to pass additional
information to the handler. One handy
use of this parameter is to work
around issues caused by closures
Try this code:
function foo(val) {
alert(val);
}
var funMaker = function(k) {
return function() {
foo(k);
};
};
for (var i = 0; i < 3; i++) {
$('#button'+i).click(funMaker(i));
}
Some important points here:
JavaScript is function scoped. If you want a new ('deeper') scope, you need to create a function to hold it.
This solution is Javascript specific, it works with or without jQuery.
The solution works because each value of i is copied in a new scope as k, and the function returned from funMaker closes around k (which doesn't change in the loop), not around i (which does).
Your code doesn't work because the function that you pass to click doesn't 'own' the i, it closes over the i of its creator, and that i changes in the loop.
The example could have been written with funMaker inlined, but I usually use such helper functions to make things clearer.
The argument of funMaker is k, but that makes no difference, it could have been i without any problems, since it exists in the scope of the function funMaker.
One of the clearest explanation of the 'Environment' evaluation model is found in 'Structure and Interpretation of Computer Programs', by Sussman & Abelson (http://mitpress.mit.edu/sicp/ full text available online, not an easy read) - see section 3.2. Since JavaScript is really Scheme with C syntax, that explanation is OK.
EDIT: Fixed some punctuation.
#Andy solution is the nicest. But you can also use Javascript scoping to help you save the value in your closure.
You do so by creating a new scope in your loop body by executing an anonymous function.
for (var i = 0; i < 3; i++) {
(function(){
var index = i;
$('#button'+index).click(function(){
foo(index);
});
})();
}
Since the loop body is a new scope at each iteration, the index variable is duplicated with the correct value at each iteration.
Use the .each function from jquery - I guess you a looping through similar elements - so add the click using something like:
$(element).children(class).each(function(i){
$(this).click(function(){
foo(i);
});
});
Not tested but I always use this kind structure where possible.
Or just manufacture a new function, as you describe. It would look like this:
function foo(val) {
return function() {
alert(val);
}
}
for (var i = 0; i < 3; i++) {
$('#button'+i).click(foo(i));
}
I'm pretty sure Mehrdad's solution doesn't work. When you see people copying to a temporary variable, it's usually to save the value of "this" which may be different within an inner child scope.

Effective javascript book having trouble understanding item 13(Iffy)

Trying to read this wonderful book of effective javascript(but I am still novice)..
In item 13, it talks about immediately invoked function expression to create local scopes.
I unfortunately however cannot wrap my head around below example
function wrapElements(a) {
var result = [], i, n;
for ( i = 0, n = a.length; i < n; i++ ) {
result[i] = function() { return a[i]; };
}
return result;
}
var wrapped = wrapElements([10,20,30,40,50]);
var f = wrapped[0];
f(); // undefined....
I really try to read that page many times but I still don't understand
Especially below statement from the book.
The bug in the program comes from the fact that the programmer apparently expected the function to store the value of i at the time of the nested function was created. But in fact, it contains a reference to i. Since the value of i changes after each function is created, the inner functions end up seeing the final value of i. This is the key point about the closures.
Closures store their outer variable by reference, not by value.
I honestly think I understand closure storing info by reference and not by value but I honestly cannot relate them to above paragraphs.
Can someone please explain this to me in easier terms or point me to article which does this? I was not able to find any that was easy to understand.
Thank you for your time in advance!!
Let me see if I can help you understand a little. The concept of Immediately-Invoked Function Expressions or (the popular term back when I learned them) Self-Executing Anonymous Functions can be a difficult one to grasp and I recommend that you have a solid knowledge of JavaScript before really digging in, but I may be able to help explain it to you in a way that will help you understand.
So - let's start by examining a normal function declaration that can be done one of two ways:
function someFunction (param1, param2) {
//do stuff
};
OR
var someFunction = function (param1, param2) {
//do stuff
};
And to invoke this function, you would call it like so:
someFunction("param1value", "param2value");
Which is great and works exactly how it's supposed to. But what if you need a function that executes or invokes immediately when it's ran, and don't want to add an object to the global namespace? Here's the real benefit of an IIFE (SEAF). Here is the basic structure of an anonymous function:
(function () {
})();
The first set of parenthesis after (function () { pass parameters into the scope of the function. The second set of parenthesis })(); are used to invoke the function and pass parameters into the function. Wrapping the function declaration in parenthesis makes the function anonymous and allows it to execute or invoke immediately.
Let's take a very basic beginning framework example and explain in a little more detail:
(function (window, undefined) {
})(window);
I remember when I first saw this, I couldn't figure what was going on here and what the point was... This function accepts two parameters to pass into the scope of the function, a window object and an undefined object. (function (window, undefined) { Then when we call it, we pass in only one window object (the global window scope). })(window); To help you understand, this would be like writing a function and executing it like this:
function doStuff (window, undefined) {
//do stuff here
};
doStuff(window);
So why don't people just write their code this way instead of worrying about these IIFE's? Well, writing your functions this way, could clog up your global scope, meaning that now you have a doStuff() object defined that is available across the scope of your entire project. If you have a really large project or framework, you typically only want to expose one object to the global scope, and keep everything else anonymous so it doesn't overwrite or get overwritten by additional code that may also be included in the application.
This is really the basics, but to help you understand the syntax a little more, let me do a real basic working example for you, just to help you wrap your head around the concept. In this example, as soon as the code runs, we're just going to multiply two numbers, whichever two numbers you pass into the function. Then we're going to output the result to a text box with the id "result". You can play around with it here: http://jsfiddle.net/k7f4n0mk/
(function (number1, number2) {
document.getElementById("result").value = (number1 * number2);
})(5, 10);
If we were to write this without an IIFE, you would first have to define the function, then invoke it and it would look like this:
function multiply(number1, number2) {
document.getElementById("result").value = (number1 * number2);
};
multiply(5, 10);
You can see this example here: http://jsfiddle.net/k7f4n0mk/1/
Both examples produce the exact same result, and I'm assuming that you're fairly comfortable with the second one since it's one of the very basics of the language, so why should you worry about this whole new way to write a function if you're old way works just fine? Well, again, this goes back to keeping the global scope clean, and protecting the local scope.
Everyone is pretty familiar with the jQuery javascript library. The entire context of jQuery is wrapped in an IIFE and only the jQuery and the alias $ object are exposed to the global scope - that's pretty impressive for everything that jQuery does. Well, if jQuery didn't have this IIFE syntax, then every function that they declared would be available to the global scope and could easily be overwritten by an unknowing user. They could overwrite any of the function that jQuery uses and completely break the library - so we want to protect all of the functions that jQuery uses (local scope) and keep the global scope clean by only exposing the necessary objects (jQuery and $).
I know this has been a really long answer, but I hope that I have been able to help you gain a little more understanding on this subject. Let me know if you have any other questions.
-EDIT-
To the point of your question - let me see if I can help explain in greater detail.
Here is the code that you are using:
function wrapElements(a) {
var result = [], i, n;
for (i = 0, n = a.length; i < n; i++) {
result[i] = function () { return a[i]; };
}
return result;
}
var wrapped = wrapElements([10, 20, 30, 40, 50]);
var f = wrapped[0];
f();
Now, when you call var wrapped = wrapElements([10, 20, 30, 40, 50]);
wrapped is now referencing an array of functions, because that's what you're returning in your for loop:
wrapped = [function () { return a[i]; },function () { return a[i]; },function () { return a[i]; },function () { return a[i]; },function () { return a[i]; }]
Then, when you call var f = wrapped[0], f becomes a reference to the first function in the array
f = function () { return a[i]; }
So, what you are doing in this code, is adding a new function to the array in your loop. If you try to call the function, a and i will be undefined which is why you are receiving an undefined error.
To achieve the desired results, the code would look like this:
function wrapElements(a) {
var result = [], i, n;
for (i = 0, n = a.length; i < n; i++) {
result[i] = a[i];
}
return result;
}
var wrapped = wrapElements([10, 20, 30, 40, 50]);
var f = wrapped[0];
I hope this helps your understanding a little more. Please let me know if you need any further assistance.
This is a very common bug. Let me simplify it for you.
The following program should alert 1, 2 and 3:
for (var i = 1; i <= 3; i++) {
setTimeout(function () {
alert(i);
}, 10);
}
However, as you can see it alerts 4 3 times instead. What's happening is that by the time the function given to setTimeout is called the value of i has changed. That's the same problem that you are facing.
To solve this problem we make use of immediately invoked function expressions (IIFEs).
for (var i = 1; i <=3; i++) {
(function (new_i) {
setTimeout(function () {
alert(new_i);
}, 10);
}(i));
}
By using an IIFE we're creating a new variable called i whose value is the that of the old i. Now when the old i changes, the new i remains the same. Hence we get the expected result.
A better way to write this would be to use the with statement to create a new i as follows:
for (var i = 1; i <= 3; i++) {
with ({ new_i: i }) {
setTimeout(function () {
alert(new_i);
}, 10);
}
}
Using with is better than the IIFE for 2 reasons:
It's cleaner and easier to read and understand.
It's faster because no function is being invoked. Function invocation is slow.
Hope that helps.

assign a function into a variable and run itself

I have read a interested blog where this above technique is applied, i understand it will run the function itself. but what's the purpose assign to a variable, when i try to console.log the variable i get undefiend.
var test1 = (function(){
console.log('yay')
})();
console.log(test1)
what's the differnet doing this way below
(function test1(){
console.log('yay');
})();
Suggestion are appreciated. :)
The immediately invoked function expression (IIFE) in Javascript serves to introduce a closure via a new scope. This is often done to compensate for the lack of block scoping in Javascript or provide information hiding a la module pattern (seen often in jQuery plugins).
Minimal example below:
var counter = (function() {
var i = 0;
function inc() {
i++;
return i;
}
return inc;
})();
The return exposes assigns the function inc to the variable counter. Successive invocations of counter() will result in 1, 2, etc. while keeping i hidden.
This is roughly equivalent to an object oriented approach that declared i as private.
In your sample above the function is void which makes no sense to assign the function result to a variable since it is returning nothing:
However tweaking your sample a little bit:
var test1 = (function(){
console.log('yay'); return "hello";
})();
then it makes sense since test1 will return "hello".
So in your original sample there are not differences and the fact that you assign a the result of a function which is not returning values is a bit odd.

Why Self-Executing Anonymous Functions

Today I came a cross the self executing functions, than somehow I ended up knowing about
Self-Executing Anonymous Functions, then I've read this article: http://briancrescimanno.com/how-self-executing-anonymous-functions-work/
The thing is that I don't know WHY to use Self-Executing Anonymous Functions because if I need to do something like:
var test = "a";
(function(foo) {
alert(foo);
})(test);
I could just make something like:
var test = "a";
alert(foo);
Or did I miss anything?
also this can be done to any code inside the function, but I used alert() to make simple
Update:
Even thought I've already accepted and answer I would like to share something I've found, if anyone came across this question later :)
Using this notation we can also make an endless loop like following:
(function loop(){
// do something here
loop();
)();
There are a couple of reasons why one would use an IIFE:
1) No littering
var a = 'foo';
alert(a);
vs
(function() {
var a = 'foo';
alert(a);
}())
Both examples do the same thing, but in the second example there is no a variable inside the outer scope.
2) State capturing
var a = 'foo';
window.setTimeout(function() { alert(a); }, 1);
a = 'bar';
vs
var a = 'foo';
window.setTimeout( (function(a_copy) {
return function() { alert(a_copy); }
}(a)), 1);
a = 'bar';
The first example alerts bar, while the second alerts foo. You will find this technique used especially with loops.
Your initial example isn't worth to be executed in an anonymous function, so its a bad example to understand WHY to use this technique. Here is a good example to explore state capturing:
var list = [{id: 1, data: null}, ...];
for (var i = 0; i < list.length; i++) {
(function(item) {
// start async request, for each item in the list, in the order of the list
asyncAjax("get-data-from-somewhere.json?what=" + list[i].id, function (response) {
// thats the on success callback, which gets executed when the server responded
// each item will have different response times, therefore the order of response is various
// if we would use simply list[i].data, it wouldn't work correctly, because "i" would has the value of list.length, because the iteration has been finished yet.
item.data = response;
});
})(list[i]); // the function will preserve the reference to the list item inside, until the function has been fully executed
}
When writing sync. code, you can always fallback to classic object oriented style of structering your code. So you can avoid closures / instant-anonymous function calls. But as soon as you use async. mechanics, closures get very handy and make your code looking more clean, off course only if you can read and understand closures :)
By the way, you could also simply write:
function(private) {}(outer)
is the same as
(function(private) {})(outer)
but the second is better, because its simply more obvious for the reader.
The syntax you describe is commonly referred to as an "immediately invoked function expression", or IIFE.
One of the common use cases is to emulate private variables:
var ns = (function () {
var x = 1; // "private"
return {
getX: function () {
return x;
}
}
}());
ns.getX(); // 1
ns.x; // undefined because x is "private"
In that example the x variable is local to the IIFE. It's not directly accessible outside of it. However, since it is referred to by the getX method, which is accessible outside of the IIFE (because it's part of the returned object) a reference to x is kept alive. This is what is usually meant by the term "closure".
Self executing functions are not really useful if you just do an alert inside.
Consider something like this:
(function(foo) {
var a = ..
// do something with a and foo
})(test);
The advantage here is that a is "private" inside the method and cannot be used outside the method. So a doesn't end up as a global variable and can't be overwritten by some other piece of javascript which uses a variable of the same name.

What is the significance of declaring another function within a function with regards to closures in JavaScript?

I'm still struggling to wrap my mind around closures in JavaScript (for the record, I've read the answer to JavaScript closures here on Stack Overflow, plus the "JavaScript Closures for Dummies" and am still puzzled by them).
My main issue is that I'm having trouble understanding the significance of declaring another function within a function; I get that returning the inner function allows the local variables of the outer function to remain active, but isn't that still the case in this example?
function sayName(name) {
var say = "Hello, " + name;
alert(say);
}
var sayJohn = sayName("John");
The local variable, "say" is still being referenced outside of its local scope in the sayJohn() function that I've created.
So isn't this still creating a closure?
N.B I apologize for how garbled this all sounds, still very fresh to learning JavaScript and programming in general, so please go easy on me!
Your example indeed cannot show the power of closure.
Look at this instead:
function makeAdder(add1){
return function(add2){
return add1 + add2;
};
}
// add10 is a function which increments the input by 10(that's the closure's magic)
var add10 = makeAdder(10);
add10(12); // returns 22
add10(9); // returns 19
While #HuiZheng's answer is correct, here's a simpler use case for closures:
var getUniqueID = (function () {
var counter = 0;
return function () {
return counter++;
};
}());
getUniqueID(); // 0
getUniqueID(); // 1
getUniqueID(); // 2
say is not being referenced outside sayName function. "alert" is being called from inside sayName function and hence still in the scope of sayName.
closure is a function reference which keeps the outer function variables still active even after the outer function has been removed from the call-stack

Categories

Resources