0

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?

Dave Newton
  • 152,765
  • 23
  • 240
  • 286
gaussclb
  • 1,057
  • 2
  • 8
  • 22
  • 5
    No, x still references the same `A` object. Also, `x` doesn't have the property `attr`, that would be what would happen if you said `x.attr = 1`, which is not what you did. `x`'s *prototype* has the property `attr`, just like you wrote. – Dave Newton Jul 30 '18 at 13:08
  • But the first time, I invoke `document.write(x.attr+"
    "); `, x's prototype don't have property `attr`, so x's prototype is reallocated?
    – gaussclb Jul 30 '18 at 13:14
  • 1
    No, `x`'s prototype gets a new property. It's unclear what you mean by "reallocated" here. – Dave Newton Jul 30 '18 at 13:15
  • 1
    if you want to understand it better, you should read this article: https://hackernoon.com/prototypes-in-javascript-5bba2990e04b – Matheus Pitz Jul 30 '18 at 13:29
  • A literal reading of your question **cannot** be answered: whether or not a particular line of code triggers a reallocation is not only implementation dependent, but dependent on *how the program runs*. Is reallocation really what you're concerned with here? – Jared Smith Jul 30 '18 at 13:52

4 Answers4

2

No. 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.

Damodar Dahal
  • 519
  • 4
  • 15
2

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.

cheekujha
  • 641
  • 4
  • 12
  • Do you mean when we execute `A.prototype.attr = 1; ` All existed instances of `A` will add `attr` to `instance.__proto__`? – gaussclb Jul 30 '18 at 13:29
  • No, it doesn't have to add to every **instance**. By default `instance.__proto__` is referencing `A.prototype`. So there is only one **attr** property which is used by all instances – cheekujha Jul 30 '18 at 14:29
0

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'.

0

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 to A.prototype. So when we add attr to A.prototype, all instances of A don't change.

  • When we change attr of a instance, it doesn't change instance.__proto__.attr, it add attr to 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
gaussclb
  • 1,057
  • 2
  • 8
  • 22