Understanding Javascript's OOP: instances modi

2019-04-10 13:38发布

问题:

I'm having some trouble understanding why modifying a property in instance a modifies the same property on instance b.

var A = function (){

};

A.prototype.data = {
    value : 0
};

var a = new A();
var b = new A();

console.log(a.data.value, b.data.value); // 0, 0
a.data.value = 5;
console.log(a.data.value, b.data.value); // 5, 5

Shouldn't the prototype keyword make the data variable an instance variable ?

This seems not to be the case in this example which executes as expected:

var B = function (){
    this.data = {
        value : 0
    };
};

var i = new B();
var j = new B();

console.log(i.data.value, j.data.value); // 0, 0
i.data.value = 5;
console.log(i.data.value, j.data.value); // 5, 0

I'm confused as why the prototype method wont work. Maybe i'm lacking some conceptual knowledge.

回答1:

Prototype in js is a data shared between all instances of that class, it's like a static variable from classic oop languages. Sometimes it's usefull to put some methods/fields in .prototype to save memory on runtime.



回答2:

Because it's really doing this:

var A = function (){

};

var someObj = { value:0 };

A.prototype.data = someObj;

So all instances of A now have a property named data which points to the object someObj. Across all instances, this is the same object. And you are changing the value inside that object.

A does not own value. It holds a reference to an object that owns value.



回答3:

Shouldn't the prototype keyword make the data variable an instance variable ?

It does exactly the opposite. The A.prototype is shared by all objects created by A. When you index an object created by A, if the index is not present, JavaScript will attempt to resolve that index via the object's prototype (e.g. o.constructor.prototype). In this case, you're indexing a and b with data, which doesn't exist in those objects, so it uses the one in their prototype.



回答4:

a and b have the same prototype. so their prototypes share properties. this is the difference between classical and prototypal inheritance.



回答5:

Just the opposite. The prototype is shared among all instances. JavaScript is a prototypal language, which is more general than classic OO languages. I good summary is Prototypal inheritance. You also might learn a little about the io language which is a more "pure" prototypal language that might help to understand JavaScript better.