Yogesh Ghimire
Yogesh Ghimire

Reputation: 442

Javascript: Why an instance is able to change the array but not other properties that are defined in the prototype?

I am confused why an instance of a Person, for example, person1 is able to change the property jobs, which is an array, defined in Person.prototype but not other properties like name and height. This is seen when person2 calls the properties from Person.prototype after person1 tries to modify its properties. I appreciate any ideas or thoughts. Thank you.

function Person(){

}

Person.prototype = {
    constructor : Person,
    name: "Hello",
    height: 6,
    jobs: ['developer', 'student'],
    getInfo: function(){
        alert("My name is "+this.name+" and my height is: "+this.height+" feet");
    }
}

var person1 = new Person();
person1.height = 5;
person1.name = "World";
person1.jobs.push('cook');
alert(person1.jobs); //developer, student, cook
alert(person1.height); //5
alert(person1.name); //World

var person2 = new Person();
alert(person2.height); //6
alert(person2.jobs); //developer, student, cook
alert(person2.name); //Hello

Upvotes: 1

Views: 32

Answers (2)

Navaneeth
Navaneeth

Reputation: 2584

In case of jobs, you are mutating the object rather than re-assigning the object.

In case of person1.height = 5;, you are assigning. So, it assigns to person1 but not to the prototype. In case of jobs, you are just mutating, so the effects are visible. Go through prototypical inheritance to learn more about it.

Upvotes: 0

T.J. Crowder
T.J. Crowder

Reputation: 1073998

Because when you do

person1.height = 5;

The object person1 refers to gets its own height property, which hides the height it inherits from its prototype.

But when you do:

person1.jobs.push('cook');

you're not assigning to jobs, you're just changing the state of what jobs refers to (the array). So you're changing the one on the prototype.

If you did:

person1.jobs = ['cook'];

that would be like our height example, person1 would get its own jobs property. If you want to keep the jobs that the prototype had, you could copy the array first:

person1.jobs = person1.jobs.slice();
person1.jobs.push('cook');

Let's look at what's going on in memory:

When you've created your Person function and the object on its Person.prototype property, we have this in memory:

       +------------------------------------------+
       |                                          |
       |                                          |
        \  +------------+                         |
Person---->| (function) |                         |
           +------------+     +---------------+   |              
           | prototype  |---->|   (object)    |   |              
           +------------+     +---------------+   |              
                              | constructor   |---+              
                              | getInfo       |------>(not shown)
                              | name: "Hello" |                  
                              | height: 6     |      +----------------+
                              | jobs          |----->|     (array)    |
                              +---------------+      +----------------+
                                                     | 0: "developer" |
                                                     | 1: "student"   |
                                                     +----------------+

Then we do

var person1 = new Person();

and we have this:

       +----------------------------------------------+
       |                                              |
       |                                              |
        \  +------------+                             |
Person---->| (function) |                             |
           +------------+         +---------------+   |              
           | prototype  |-------->|   (object)    |   |              
           +------------+       / +---------------+   |              
                               |  | constructor   |---+              
                               |  | getInfo       |------>(not shown)
                               |  | name: "Hello" |                  
                               |  | height: 6     |      +----------------+
                               |  | jobs          |----->|     (array)    |
                               |  +---------------+      +----------------+
                               |                         | 0: "developer" |
                               |                         | 1: "student"   |
                               |                         +----------------+
           +---------------+   |
person1--->|   (object)    |   |
           +---------------+   |
           | [[Prototype]] |---+
           +---------------+

When you do this:

person1.height = 5;

person1 gets its own height (everything else stays the same):

                              (to Person.prototype)
           +---------------+   |
person1--->|   (object)    |   |
           +---------------+   |
           | [[Prototype]] |---+
           | height: 5     |
           +---------------+

But doing person1.jobs.push('cook'); just changes the state of the array jobs points to:

       +----------------------------------------------+
       |                                              |
       |                                              |
        \  +------------+                             |
Person---->| (function) |                             |
           +------------+         +---------------+   |              
           | prototype  |-------->|   (object)    |   |              
           +------------+       / +---------------+   |              
                               |  | constructor   |---+              
                               |  | getInfo       |------>(not shown)
                               |  | name: "Hello" |                  
                               |  | height: 6     |      +----------------+
                               |  | jobs          |----->|     (array)    |
                               |  +---------------+      +----------------+
                               |                         | 0: "developer" |
                               |                         | 1: "student"   |
                               |                      +->| 2: "cook"      |
                               |                      |  +----------------+
           +---------------+   |                      |
person1--->|   (object)    |   |                      |
           +---------------+   |          NOTE WHAT   |
           | [[Prototype]] |---+          CHANGED ----+
           | height: 5     |
           +---------------+

Upvotes: 1

Related Questions