Reputation: 373
I am quite new to javascript and i have encounter problems about function call and the closure.
Below are the code that i tried in w3schools,
<!DOCTYPE html>
<html>
<body>
<p>Counting with a local variable.</p>
<button type="button" id="btn">Count!</button>
<p id="demo">0</p>
<script>
var add = (function (test) {
var counter = 0;
return function (test) {return counter += test;}
})();
/*function add(test){
var counter = 0;
return function (test) {return counter += test;}
}*/
function myFunction(){
document.getElementById("demo").innerHTML = add(123);
//document.getElementById("demo").innerHTML = add().call(this, 123);
}
var btn = document.getElementById("btn");
btn.addEventListener("click", myFunction);
</script>
</body>
</html>
It works fine for the current code, that every time i press the button, the number in the paragraph(id="demo") increment by 123.
But when i tried the commented code, which create a function with closure with exact same code, the paragraph value remain at 123 every onclick.
In this situation, i have a few questions to ask.
1.For the code :
var add = (function (test) {...}) ();
What is the usage of the last bracket? If we provide parameter to the last bracket, how can we use it in the declaration of the anonymous function of variable (var add)?
2.Why these two ways to define the function result in different result?
Thanks a lot, any help is appreciated.
EDIT
<!DOCTYPE html>
<html>
<body>
<p>Counting with a local variable.</p>
<button type="button" id="btn">Count!</button>
<p id="demo">0</p>
<script>
/*var add = (function (test) {
var counter = 0;
return function (test) {return counter += test;}
})();*/
function add(test){
var counter = 0;
return function (test) {return counter += test;}
}
function myFunction(){
//document.getElementById("demo").innerHTML = add(123);
document.getElementById("demo").innerHTML = add().call(this, 123);
}
var btn = document.getElementById("btn");
btn.addEventListener("click", myFunction);
</script>
</body>
</html>
It seems that the code run with no error occur, when i use the commented code for declaration of function, but just a bug that the integer of the paragraph didn't increment.
Upvotes: 1
Views: 1292
Reputation: 2672
The reason you are getting 123 all the time is because every time you click on the button, you take a new inner function with a closure on counter variable with value 0; So value of counter
always remains 0 and when you add 123 to 0 you get 123.
If you move closure part out of the event handler, you would get exact same result as in the first case.
Notice the line var inner = add(); //<---Notice this line
. This would take the closure one time and subsequently you will keep increasing the value of counter
.
Also, notice this line inside myFunction
:
document.getElementById("demo").innerHTML = inner.call(this, 123);
Here we are calling the inner function that we had reference on earlier.
/*var add = (function (test) {
var counter = 0;
return function (test) {return counter += test;}
})();*/
function add(test) {
var counter = 0;
return function(test) {
return counter += test;
}
}
var inner = add(); //<---Notice this line
function myFunction() {
//document.getElementById("demo").innerHTML = add(123);
document.getElementById("demo").innerHTML = inner.call(this, 123);
}
var btn = document.getElementById("btn");
btn.addEventListener("click", myFunction);
<p>Counting with a local variable.</p>
<button type="button" id="btn">Count!</button>
<p id="demo">0</p>
Upvotes: 1
Reputation: 386
() The last bracket is to execute it.
The example u have shown is that of an IIFE. IIFE are used to limit scope of all ur variable so that namespaces can be demarkcated.
//without params
(function(){
//...
})()
//-OR- (both are same)
(function(){
//...
}())
//with params. if u ever wondered how that $ variable was being used in jquery, this is how.
(function(jquery){
})(jquery);
//es6
(
() => { ... }
)()
closure is a programming concept in which (otherwise) scoped-out variables are allowed to persist. DO NOT use closure with big object collections !!!
var outer = function(p1){
var inner = function (p2) {
return (p1 + p2);
return inner;
}; //outer ends.
var x = outer(10);
x(20); //20 + 10;
x(30); //30 + 10;
x(40); //40 + 10;
Upvotes: 0
Reputation: 350
Upvotes: 0