1

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.

asked May 22, 2017 at 9:26
7

3 Answers 3

1

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>

answered May 22, 2017 at 10:02
Sign up to request clarification or add additional context in comments.

Comments

0
  1. () is to invoke the anonymous function you just declare, and it return another anonymous function. If you provide a parameter, it will be fed to your function (test). In this case, you don't actually need the first test parameter. It's just not used.
  2. For your commented code, it returns a function. And the function is never invoked.
answered May 22, 2017 at 9:35

1 Comment

May i ask in this case, in what way i can invoke the function?
0

() 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;
answered May 22, 2017 at 9:49

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.