Reputation: 442
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
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
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