2

So the code below reflects the pseudo-classical version of inheritance in JavaScript.

function SynthOne() { // constructor 1
    this.sound1 = "piano";
};

function SynthTwo() { // constructor 2
    this.sound2 = "bass";
}

SynthOne.prototype = new SynthTwo; // overwrite constructor 1's prototype with constructor 2's
var synthsCombined = new SynthOne; // assign constructor 1 to variable

// this variable now has access to both constructors properties & methods

document.write(synthsCombined.sound1 + " ")
document.write(synthsCombined.sound2)

But let's change this to make sound1 and sound2 to simply sound.

Let's also assume that I really wanted to create an inheritance chain to access both of these "sounds" even if they were named the same thing. Is there a pattern in the JavaScript community or a coding convention that exist to deal with this kind of situation? Or am I just stuck?

Thank you

Wayne
  • 59,728
  • 15
  • 131
  • 126
William
  • 4,422
  • 17
  • 55
  • 108
  • 1
    What do you want to do with `synthsCombined`, what "combine" would you expect? In inheritance it's totally normal that child properties shadow those of the parent - that's just what you'd want. Maybe "inheritance" is not the solution to your [problem](http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem). – Bergi Jan 16 '14 at 21:15
  • I am not using this code for anything , it was simply something that entered my mind and I was curious about. I can see a situation where at the very least you combine constructors not realizing they have similar property/method names. I thought there might be a conventional "way" to deal with this that I did not know about. – William Jan 16 '14 at 21:18
  • Trouble is that the solution depends on real-world demands. Can/Should the value(s) of the property be shared among all objects created from those constructors? If so, then you can fetch the next object in the prototype chain, and get the value. If not, then an object clearly can't have two values assigned at the same time. You'd probably need a map or array of values. Again, all depends on the actual situation. – cookie monster Jan 16 '14 at 21:19
  • Overriding and extening parent functions are covered in this answer:http://stackoverflow.com/a/16063711/1641941 it's better to use Object.create or a helper function to set up prototype part of inheritance instead of creating an instance of Parent – HMR Jan 17 '14 at 02:10

3 Answers3

3

Child properties hide properties of the same name further up the prototype chain. Technically, you can still get access to the parent property like this:

Object.getPrototypeOf(synthsCombined).sound

Or the non-standard:

synthsCombined.__proto__.sound

But this probably isn't something you want to do. If you need both values, then name them different things.

Wayne
  • 59,728
  • 15
  • 131
  • 126
1

it was simply something that entered my mind and I was curious about. I can see a situation where at the very least you combine constructors not realizing they have similar property/method names.

You hardly inherit from classes whose set of properties1 you do not know. If you subclass something, you often want to explicitly overwrite properties with more specific values - that's just what the shadowing is for.

In case you want to extend the set, you'd have to choose an unallocated name. In case of interface clashes (e.g. when extending the implementation), that's just a bug and either the base class or the child classes would need to change their identifier. Using descriptive names will lower the risk.

How to deal with this kind of situation?

If it's unwanted, fix the bug (this is not JavaScript-specific). If you deliberately have chosen the same property name, you can access the inherited value by manually ascending the prototype chain with Object.getPrototypeOf().

[1]: Speaking of both attributes and methods, as they're just properties in javascript

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
0

You could give one of your constructors a base property, which will get the properties from the inherited constructor:

function SynthOne() { // constructor 1
    this.base = {};
    this.sound = "piano";

    SynthTwo.call(this.base);
};

function SynthTwo() { // constructor 2
    this.sound = "bass";
}

SynthOne.prototype = Object.create(SynthTwo.prototype);
var synthsCombined = new SynthOne; 
console.log(synthsCombined.sound);         //piano
console.log(synthsCombined.base.sound);    //bass

But from what it looks like you are trying to accomplish, maybe inheritance is not the right way for you. It might make more sense to create a generic Synth class and maybe a SynthCollection class, to combine different Synths.

basilikum
  • 10,378
  • 5
  • 45
  • 58