0

In javascript if I need objects each to have an individual value of an attribute, I can just set it in the constructor, like so:

function A(x) {
    this.a = x;
}

If I want a certain attribute to be shared among the objects, I can set it in the prototype of constructor function.

function B() {}
B.prototype.b = 'B0';

But what to do in in-between situation? Basically, I have an existing code where all the constructed objects inherit a property from a prototype, but now I need to divide them into several groups so all members of a group share an attribute.

Is there a way to specialize the constructor function B somehow?

1 Answer 1

1

B.prototype.b does NOT create a static property as you presume. It's a bit more complicated than that, properties attached to a prototype share their value with other instances, until they overwrite that value, meaning that:

var Foo = function(){
};
Foo.prototype.bar = 'bar';

var f1 = new Foo();
console.log( f1.bar ); //outputs 'bar'
var f2 = new Foo();
console.log( f2.bar ); //outputs 'bar'

f2.bar = 'notbar';
console.log( f2.bar ); //outputs 'notbar'
console.log( f1.bar ); //outputs 'bar'

The only way to have "real" static properties is to attach them to the constructor function itself:

Foo.bar2 = 'bar2';

instances of Foo will have to access that value with Foo.bar2.

So the answer to your question is to create "subclasses" (constructor functions that inherit their prototype from a base constructor function) for each group and attach a property per subclass, like this:

var Base = function(){
};
Base.prototype.getSomething = function(){
    return this.constructor.something;
};
Base.prototype.setSomething = function( value ){
    this.constructor.something = value;
}
var Group1 = function(){
};
Group1.prototype = new Base(); //classical inheritance
Group1.prototype.constructor = Group1;
Group1.something = 'something';
var Group2 = function(){
};
Group2.prototype = new Base(); //classical inheritance
Group2.prototype.constructor = Group2;
Group2.something = 'something else';

var g1a = new Group1();
var g1b = new Group1();
var g2a = new Group2();
var g2b = new Group2();

g1a.setSomething( 'whatever' );

console.log( g1a.getSomething() ); //outputs 'whatever'
console.log( g1b.getSomething() ); //outputs 'whatever'
console.log( g2a.getSomething() ); //outputs 'something else'
console.log( g2b.getSomething() ); //outputs 'something else'

Warning: Group1.prototype = new Base(); is actually bad practice, I wrote a blog post about 3 types of inheritance just a few days ago which explains why:

http://creynders.wordpress.com/2012/04/01/demiurge-3-types-of-javascript-inheritance-2/

Sign up to request clarification or add additional context in comments.

2 Comments

Great! But what if my constructors actually have arguments?
What exactly do you mean? Group1 and Group2 ARE normal constructors that can have arguments. If they need to call the super constructor they can either call it directly like this: Base.call( this )' or you can do the __super__` trick as in my blogpost.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.