Why are my JavaScript object properties overwritten by other instances?

I created an object like the following.

var BaseObject = function(){ var base = this; base.prop; base.setProp = function(val){ base.prop = val; } } 

When I call the setProp method, I get the following.

 var a = new BaseObject(); var b = new BaseObject(); a.setProp("foo"); b.setProp("bar"); console.log(a.prop); // outputs 'foo' console.log(b.prop); // outputs 'bar' 

Then I created another object that inherits from BaseObject like this.

 var TestObject = function(){ // do something } TestObject.prototype = new BaseObject(); 

When I do the same, I get a result that I did not expect.

 var a = new TestObject(); var b = new TestObject(); a.setProp("foo"); b.setProp("bar"); console.log(a.prop); // outputs 'bar' console.log(b.prop); // outputs 'bar' 

I do not know why. I have read a lot lately about closure and prototype inheritance, and I suspect all of this is messed up. Thus, any pointers to why this particular example works the way it did would be greatly appreciated.

+5
source share
2 answers

There is only one BaseObject instance from which all TestObject is inherited. Do not use instances to create prototype chains!

What would you like:

 var TestObject = function(){ BaseObject.call(this); // give this instance own properties from BaseObject // do something } TestObject.prototype = Object.create(BaseObject.prototype); 

See JavaScript Inheritance: Object.create vs new , Fix javascript inheritance and What is the reason for using the 'new' keyword in Derived.prototype = new Base for a detailed explanation of problems with new . Also see Crockford 's Prototypal Inheritance - Nested Object Issues

+3
source

Think of protoypal inheritance as working exclusively with objects and without the concept of classes. In the code, you have a BaseObject that has the prop attribute. You have 2 more objects that extend from 1 instance of this object, but the property belongs to the original object. If you need each object to have its own copy, you need to provide it with a separate variable that would be initialized for this object (for example, in their constructor).

As an aside, Java-style accessors are too overloaded with JavaScript (you can intercept access initially if necessary) and may further confuse these issues, as they will behave differently.

+2
source

All Articles