0

I am trying to understand closures. In the code below, I create an instance of the constructor function Ninja and I call the instance kawazaki. I expected to be able to access the methods of Ninja. However, I am getting a TypeError: Object #<Ninja> has no method 'feints' instead.

The output I expected was 1.

Here is my code:

function Ninja() {
    var feints = 0;

    function getFeints() {
        return feints;
    }

    function feints() {
        feints++;
    }
}

var kawazaki = new Ninja();

kawazaki.feints();

console.log(kawazaki.getFeints());
Aadit M Shah
  • 72,912
  • 30
  • 168
  • 299
Mozein
  • 787
  • 5
  • 19
  • 33
  • 2
    You just created functions inside the constructor. To be able to use them as methods of new instance of `Ninja`, you should save this functions to the `this` object: `this.getFeints = function(){ ... }` and `this.feints = function(){...}` – Anatoliy Arkhipov Apr 19 '15 at 05:48
  • 2
    *"I expected to be able to access the methods of Ninja."* JavaScript is not as magical as you seem to think it is. `getFeints` and `feints` are just functions local to `Ninja`. They are not accessible from the outside and only exist during the execution of `Ninja`. – Felix Kling Apr 19 '15 at 06:41
  • @FelixKling they always made me feel like it is. – Mozein Apr 19 '15 at 13:07

3 Answers3

2

Try this instead:

var kawazaki = new Ninja;

kawazaki.feints();

alert(kawazaki.getFeints());

function Ninja() {
    var feints = 0;

    this.getFeints = function () {
        return feints;
    };

    this.feints = function () {
        feints++;
    };
}

You need to assing public properties to this within the constructor function.

Aadit M Shah
  • 72,912
  • 30
  • 168
  • 299
0

The scope of the functions getFeints and feints is limited to the function Nija. As you can not access to variables declared in a function, you can not access to those functions.

To be able to execute kawazaki.feints(), you have to "attach" the function to the Ninja function, as an object (which a function also is)

You will find in these resources several ways to achieve that, and also some deeper explanations:

Community
  • 1
  • 1
Gaël Barbin
  • 3,769
  • 3
  • 25
  • 52
0

Closure is a very simple yet largely misunderstood topic.

function Ninja() {
    var feints = 0;

    function getFeints() {
        return feints;
    }

    function feintsInc() {
        feints++;
    }

}

You have defined the closure alright but please note that a closure is not actually a method of the object. In order to get your desired output you need to call the closures just before closing the object.

feintsInc();
getFeints();

If,however, you wish to do it as

kawazaki.feintsInc();

you need to use this keywords in your function to get the functions assigned to the object.

Note,make sure your functions and variable names don't overlap.
Mayur Buragohain
  • 1,566
  • 1
  • 22
  • 42