开发者

Prototype object can be changed from instance

Could someone explain this to me in a sensible way:

function One() {}

One.prototype.obj = { key: 'value' };
One.prototype.str = 'string';

var inst1 = new One(),
    inst2 = new One();

// now let’s change so开发者_开发知识库me things in our second instance

inst2.obj.key = 'buh!';
inst2.str = 'buh!';

// ok, so what happens to our other instance?

console.log( inst1.str ); // Yields 'string' (unaffected, expected)
console.log( inst1.obj.key ); // Yields 'buh!' (!!)

console.log( One.prototype.obj.key ); // is also 'buh!'

It seems that if a prototype contains an object, the instance you create using the new keyword has that object, but if you change it, you also change the prototype object, thus affecting all instances, like a sibling-inheritance-pattern...

Is this the way it’s suppose to work?


Actually, Javascript doesn't copy anything from the prototype. Everything you define on the prototype exists only once (on the prototype itself) and gets reused because the same prototype instance is passed to all objects.

When you access a property on an object, the object checks to see if it is defined on itself. If it is, it will return the value associated with that property. If it's not, it will delegate the call to its prototype, who will from now on be responsible for what happens. That's why "inheritance" (code reuse) in Javascript is better called delegation.

Things are a bit different for write access. If you set a property on the object, it will "shadow" the value locally. That's the reason why the str property is unaffected, it has actually been defined on the inst2 object. But if you delete inst2.str and do another console.log( inst2.str ) you will notice that it will return the old value.

PS: If you want a way to prevent that from happening have a look at this tutorial: http://kevlindev.com/tutorials/javascript/inheritance/index.htm

I recommend reading the entire thing, but if you just want the meat see the KevLinDev.extend function in the "Creating a subclass" section.


In short, yes. Javascript does not implicitly copy objects for you, so when you create the object literal at obj, all instances of the One class simply refer to it via reference. Instead, you need to dynamically create the obj object in the constructor:

function One(){
  this.obj = {key:'value'};
}

See also: javascript multidimensional object

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜