I've always assumed that the prototype of a function was shared among all the objects, in a sense by reference. So if you change the value of a property of the prototype, all objects that share that prototype have the values change for them as well. So for instance below it seems that instead of the property bar being shared between all objects, it is copied. Is this right? Are the properties of the prototype of the constructor simply copied to all the class objects as they are created, or are they shared by linkage?
function foo()
{
this.bar = 1;
}
function derived() { }
derived.prototype = new foo()
object1 = new derived()
object2 = new derived()
object1.bar = 2;
//but notice if I had said here derived.prototype.bar = 3, object1.bar would still equal 2 but object2.bar would equal 3
alert(object2.bar) // this prints 1;
When you assign object1.bar = 2
, you are creating an own property on object1
, this property exist only in that object instance, and it has nothing to do with its prototype.
This property on object1
will shadow the value of the one existing on derived.prototype
, this means that when you lookup object1.bar
, it will find a value directly existing on that object.
On the other side, if you lookup object2.bar
, this object doesn't have an own bar
property, so the property lookup will search on the object this one inherits from (derived.prototype
) and it will find the value 1
.
Your object structure looks something like this:
object1 -------- | bar: 2 | ----------------- -------- | derived.prototype | ---------- |------> | bar: 1 | -- foo.prototype object2 (no own properties)| ---------- | ------------------ -------- | -> | constructor: foo | | | ----------------- ------------------ -------- | v ------------------ | Object.prototype | ------------------ | v null
Where the --->
lines denote the internal [[Prototype]]
link that expresses inheritance.
For example, you have code:
function Animal() {
}
Animal.prototype.name="animal";
function Dog() {
}
Dog.prototype = new Animal
Dog.prototype.constructor=Dog;
Dog.prototype.name="dog";
object1 = new Animal();
object2 = new Dog();
As a result you have two object instances, that looked as (you can check this for example in Chrome devtools or FF firebug or...):
object1:
__proto__: (is ref into an Animal.prototype object)
constructor: function Animal()
name: "animal"
__proto__: Object (is ref into an Object.prototype object)
object2:
__proto__: (is ref into an Dog.prototype object)
constructor: function Dog()
name: "dog"
__proto__: (is ref into an Animal.prototype object)
constructor: function Animal()
name: "animal"
__proto__: (is ref into an Object.prototype object)
When you run next code (for example):
alert(object1.name); // displayed "animal"
alert(object2.name); // displayed "dog"
What happened? 1) Javascript looked for property name in object instance (in object1
or object2
). 2) When not found, it looked up in object instance proto property (that is same as prototype of class function). 3) When not founct it looked in proto of proto and next and next while not found name
property and others proto found. If as result of search property is found, then value is returned, if not found, then undefined
returned.
What happened if you execute next code:
object2.name = "doggy";
As a result you have for object2:
object2:
name: "doggy"
__proto__: (is ref into an Dog.prototype object)
constructor: function Dog()
name: "dog"
__proto__: (is ref into an Animal.prototype object)
constructor: function Animal()
name: "animal"
__proto__: (is ref into an Object.prototype object)
Property is assigned directly into instance object, but prototype object remains unchanged. And when you execute:
alert(object1.name); // displayed "animal"
alert(object2.name); // displayed "doggy"
When you need to create|change shared property of class, you can use one from next algoritms: 1)
Animal.prototype.secondName="aaa";
alert(object1.secondName); // displayed "aaa"
alert(object2.secondName); // displayed "aaa"
Animal.prototype.secondName="bbb";
alert(object1.secondName); // displayed "bbb"
alert(object2.secondName); // displayed "bbb"
// but
Animal.prototype.secondName="ccc";
object1.secondName="ddd";
alert(object1.secondName); // displayed "ccc"
alert(object2.secondName); // displayed "ddd"
2)
Create property of type object
in prototype of function class and assign values to properties of this object.
Animal.prototype.propObject={thirdName:"zzz"};
alert(object1.propObject.thirdName); // displayed "zzz"
alert(object2.propObject.thirdName); // displayed "zzz"
Animal.prototype.propObject.thirdName="yyy";
alert(object1.propObject.thirdName); // displayed "yyy"
alert(object2.propObject.thirdName); // displayed "yyy"
object1.propObject.thirdName="xxx";
alert(object1.propObject.thirdName); // displayed "xxx"
alert(object2.propObject.thirdName); // displayed "xxx"
object2.propObject.thirdName="www";
alert(object1.propObject.thirdName); // displayed "www"
alert(object2.propObject.thirdName); // displayed "www"
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With