1
<!DOCTYPE html>
<html>
<body>
<p>Counting with a local variable.</p>
<button type="button" onclick="myFunction()">Count!</button>
<p id="demo"></p>
<script>
function Add(x) {
    this.counter = x;
   return function () {return this.counter += 1;}
};
var add = Add(0);

when I replaced "var add = Add(0);" with "var add = new Add(0)" the output is showing "NaN". why? and how this is actually working?

function myFunction(){
document.getElementById("demo").innerHTML = add(); 
  for each click 1, 2, 3 ....

}
</script>
</body>
</html>
Alex
  • 8,461
  • 6
  • 37
  • 49
M Noman
  • 31
  • 3

3 Answers3

2

new is used to create a new instance, based on an existing definition (which you are storing in Add). Instead of an instance being generated, you're returning a function, so it is not working out as you expected.

This form should work:

function Add(x) {
    this.counter = x;

    this.addOne = function() {
        return this.counter += 1;
    }
}

var add = new Add(0);

function myFunction() {
    document.getElementById("demo").innerHTML = add.addOne();
}

As to your question about why your code was returning NaN, let's look at what you were doing:

function Add(x) {
    this.counter = x;
    return function () {return this.counter += 1;}
};
var add = new Add(0);
function myFunction(){
    document.getElementById("demo").innerHTML = add(); 
}

Here you declare a variable add and initialize it using new Add(0). First, the Add function declares a property in its own scope named counter and assigns it the value passed in via the parameter named x (0, in this case). Then, it returns a function. Then it exits, no longer required, and is garbage-collected. The value assigned to the counter property is discarded because the this it is attached to has gone out of scope.

You now have add as a pointer to a function. It does not have a property named counter. When you invoke the add() function, it tries to add 1 to this.counter. Since this.counter is not defined, it automatically has the value undefined.

If you try to add a number to undefined, you get NaN. Since this happens in a return statement, NaN is returned.

Dan Lowe
  • 51,713
  • 20
  • 123
  • 112
2

The difference between Add(0) and new Add(0) is that the first one calls the function within the window context. While the second one calls the function within a new {} context. Yet the this in your anonymous function will not refer to the new {} context, since it is called within the window context since add() is the same as saying window.add().

For debugging purposes, try adding some alerts or console.logs into your function:

function Add(x) {
    alert('The context Add was called with is: '+this);
    this.counter = x;
   return function () {
alert('The context the anonymous function was called with is '+this);
return this.counter += 1;}
};

Then you'll see what this points to. When window.counter is undefined, you're getting NaN since return this.counter += 1; is adding 1 to undefined resulting in NaN.

As far as solutions, one option is to bind the function to the context you want it called in:
http://jsfiddle.net/eu9r8pau/4/

Another option is to take advantage of closures by storing a reference to this:
http://jsfiddle.net/eu9r8pau/5/

You can also rewrite the code to something simpler:
http://jsfiddle.net/eu9r8pau/6/

Ultimater
  • 4,647
  • 2
  • 29
  • 43
  • Thanks for the examples. It's really helpful for me to understand the difference. Actually I am a core java programmer. Unlike Java, JavaScript's "this" keyword is really confusing! – M Noman Nov 06 '15 at 03:03
0

To add another variation to Dan Lowe's post and explanation, this time with with regards to the title of the OP's example talking about a local variable which I take to mean a private variable:

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
</head>
<body>
<p>Counting with a local variable.</p>
<button type="button" onclick="myFunction()">Count!</button>
<p id="demo"></p>
<script>
function Add(x) {
   var counter = x;
   return function () {return counter += 1;}
};
var add = new Add(0);
function myFunction(){
  document.getElementById("demo").innerHTML = add();
}
</script>
</body>
</html>

This is, I think the classic example of a closure. The variable counter stays in the scope of the function Add and only the function to increment it is public.

You can use as many instances of Add as you want and have as many independant counters. For example add another one starting at 100:

var bdd = new Add(100);
function myFunction(){
  document.getElementById("demo").innerHTML = add() + "<br />" + bdd();
}

The "related" column on the right of this page has a good explanation of Closures, please take a look.

Community
  • 1
  • 1
deamentiaemundi
  • 5,502
  • 2
  • 12
  • 20