Rui Zhang
Rui Zhang

Reputation: 39

Confused with the variable in js

function Person(name){
    var age;
    this.name = name;
    this.setAge = function(a){
        age = a;
    }
    this.getAge = function(){
        return age;
    }
}
var p0 = new Person("John");
p0.setAge(24);
console.log("p0.getAge "+p0.getAge());//p0.getAge 24
var p1 = new Person("Mike")
p1.setAge("25");
console.log("p0.getAge "+p0.getAge());//I think the output here should be p0.getAge 25,but it is p0.getAge 24
console.log("p1.getAge "+p1.getAge());//p0.getAge 25

The variable "age" does not belong to any instance of Person as there is no "this.age" in the constructor of Person and it should be shared by instance of Person at first, But the result is not what i expected. I'm confused!

Upvotes: 3

Views: 115

Answers (4)

Mouser
Mouser

Reputation: 13304

function Person(name){
    var age; //private variable
    this.name = name;
    this.setAge = function(a){
        age = a;
    }
    this.getAge = function(){
        return age;
    }
}

You've made a closure. A closure is a private environment. Or variables declared within the closure (function) are only accessible for that function. You've create two instances of your constructor person. The parser made two separate objects each containing it's own private variable age. So when you call setAge on John his private variable age is updated, but the private variable for Mike is left untouched. The variables are only accessible in their own scope, not in the global scope. Do mind that the variable isn't connected to the instance John. To make the variable public you need to do this in the constructor function person: this.age.

For getters and setters there is a new function (available in modern browsers)

Object.defineProperty

An example:

function Person(name){
    var age; //private variable
    this.name = name;

    var age = 0;

    Object.defineProperty(this, "age", {
        get : function(){return age;}, //has access to the private var `age` in this scope.
        set : function(value){age = value;}
    });
}

Now when you call John's age via p0.age you get 0. But when you do p0.age = 10 it sets the private var age to 10.

Upvotes: 0

Teddy
Teddy

Reputation: 797

The scope of variable is in function, the code works fine.

If you expect a singleton variable, a variable outside or Person.age are good ways.

Upvotes: 0

Trash Can
Trash Can

Reputation: 6824

Even though the age "property" was not implicitly declared as an instance variable, but its scope is contained within the function. And each time you call your setAge() method, it sets the new value for the age variable, if you don't call setAge() on the object, the age will be undefined which is the default value for un-initialized variables. It is not a global variable, therefore it is not shared across objects.

Upvotes: 0

Naeem Shaikh
Naeem Shaikh

Reputation: 15715

function Person(name){
    var age;
    this.name = name;
    this.setAge = function(a){
        age = a;
    }
    this.getAge = function(){
        return age;
    }
}

look var age;, you dont declare this.age, this is particularly done when you dont want variable directly accessed from outside, i.e. you try to make it private for that object, that is why you don't create a property for the object, but just a variable for that closure.

Still you can access it inside the object and return it using getAge method, but not directly with age. so there is no property age, but there exists a variable age

Upvotes: 3

Related Questions