Phyron
Phyron

Reputation: 633

Issue of prototype

I have a simple issue, but i can't understand.

<script type="text/javascript">

var man = function(){

    var age = 1;

    this.shoes = 2;

};

man.prototype = {

    create: function(){

        //age = 5;
        console.log(age);
        console.log(this.shoes);

    }

}
var man1 = new man;
man1.create();
</script>

-Ok,I create a man with 2 vars, age and shoes. I use "this" only in shoes. After I prototype a method in man.

-If I execute this code, first console.log say me:

Uncaught ReferenceError: age is not defined (logic)

And the second console is "2" (correct).

-If I write: console.log(this.age) the message error is: undefined.

-But if I put a value for age (age=5)(without using "var" for create var) in new method, it works.

Why I can only use age var if I put a value before read this but?

Upvotes: 0

Views: 38

Answers (2)

Emil Ingerslev
Emil Ingerslev

Reputation: 4785

The age variable is within the "constructors" closure, which makes it only available there. You can use the age variable inside that function (closure), but not outside.

If you want to make it accessable from outside, add it to this or make a getter function like:

var man = function(){
    var age = 1;
    this.shoes = 2;
    this.getAge = function() { return age; };
};

But if you don't put declare the variable inside the function, but still set it, then it will be defined on the global object, in the browser window. This will not make age available on the man object, but you will get access to it anywhere. Here's an to clarify a bit:

function tellAgeDelayedGlobal() {
    age = 1;
    setTimeout(function() { console.log(age) }, 1000);   
}

function tellAgeDelayedDeclared() {
    var age = 1;
    setTimeout(function() { console.log(age) }, 1000);   
}

tellAgeDelayedGlobal();
tellAgeDelayedDeclared();
age = 2;

this will print to console:

2
1

Upvotes: 2

swaroopsm
swaroopsm

Reputation: 1399

When you use var inside a function it is available within it(local scope).

var man = function(){

    var age = 1;

    this.shoes = 2;

};

Here age will be available only in the man method / constructor because this creates a local scope or rather is private to the constructor.

man.prototype = {

    create: function(){

        age = 5;
        console.log(age);
        console.log(this.shoes);

    }

}

Here age will create a global scope. That is, this is equivalent to window.age = 5 and hence making it available in the entire app. Because of which you will be able to retrieve the value in any function since it is global now.

This must be avoided since it will not be automatically garbage collected(GC). If you really need it because other parts of your code has a dependency w.r.t. it, you can namespace it like: MyApp.age = 5. But w.r.t your current situation, I do not find a need in here.

Upvotes: 2

Related Questions