See the code:
function A(){
}
var x = new A();
console.log(x.attr); // undefined
A.prototype.attr = 1;
console.log(x.attr); // 1
The memory is allocated, when we invoke new A(), and x don't have property attr, but after A.prototype.attr = 1; is executed, x has property attr.
Does it mean x is reallocated?
4 Answers 4
Confusion is caused by prototypical inheritance. x in itself doesn't have a property attr. Which can be verified by running the following:
x.hasOwnProperty('attr')
This will return false.
However x.attr references the attr property assigned to A.prototype.
To see that try to console log
x.__proto__
attr property will be visible there.
2 Comments
A.prototype.attr = 1; All existed instances of A will add attr to instance.__proto__?instance.__proto__ is referencing A.prototype. So there is only one attr property which is used by all instancesNo. x is an instance of A. When you try to access x.attr initially, its prototype, A, does not have an attribute named attr. Thus, it is equivalent to calling x.i_want_something_which_does_not_exist, which returns undefined. But after you assign A.prototype.attr, all instances of A will share that value. For example,
function A(){
}
var x = new A();
var y = new A();
document.write(x.attr+"<br>"); // undefined
document.write(y.attr+"<br>"); // undefined
A.prototype.attr = 1;
document.write(x.attr+"<br>"); // 1
document.write(y.attr+"<br>"); // 1
Edit: Here is an example of three instances:
function printValues(x, y, z){
document.write("x.attr="+x.attr+", y="+y.attr+", z.attr="+z.attr+"<br />"); // Although I strongly recomment you to never use document.write
// https://stackoverflow.com/questions/802854/why-is-document-write-considered-a-bad-practice
}
function A(){
}
var x = new A();
var y = new A();
var z = new A();
printValues(x, y, z);
A.prototype.attr = 1;
printValues(x, y, z);
y.attr = 2;
printValues(x, y, z);
produces:
x.attr=undefined, y=undefined, z.attr=undefined
x.attr=1, y=1, z.attr=1
x.attr=1, y=2, z.attr=1
Note that after running y.attr=1, y.attr has a different reference than x.attr and z.attr, which, by the way, still share same reference.
3 Comments
y.attr=2;, which means attr is not shared by x and y. So x have his own attr.You just add property attr to prototype object of A. When you call x.attr it firstly try to find it in own properties of x, and if can't find there - go to prototype of 'A'.
Comments
Thanks to @Matheus Pitz. After I read Prototypes in JavaScript, I get the perfect answer.
A.prototype is shared by all instances of A. When
new A()is executed,A().__proto__is created, and refer toA.prototype. So when we addattrtoA.prototype, all instances ofAdon't change.When we change
attrof a instance, it doesn't changeinstance.__proto__.attr, it addattrto instance.
See the example:
function A(){
}
var x = new A();
var y = new A();
A.prototype.attr = 1;
console.log(x.__proto__ === A.prototype) //true
console.log(y.__proto__ === A.prototype) //true
A.prototype.attr = 2;
document.write(x.attr+"<br>"); // 2
document.write(y.attr+"<br>"); // 2
x.attr = 3;
console.log(x.hasOwnProperty('attr')) //true,attr=3
console.log(x.__proto__) //attr=2
document.write(x.attr+"<br>"); // 3
document.write(y.attr+"<br>"); // 2
Aobject. Also,xdoesn't have the propertyattr, that would be what would happen if you saidx.attr = 1, which is not what you did.x's prototype has the propertyattr, just like you wrote.document.write(x.attr+"<br>");, x's prototype don't have propertyattr, so x's prototype is reallocated?x's prototype gets a new property. It's unclear what you mean by "reallocated" here.