20

I've seen a lot of stuff like this, and am looking for the proper solution to basic JavaScript inheritance:

function Food(){}  // Food  constructor (class)
function Bread(){} // Bread constructor (class)

var basicFood = new Food();    // Food classes will inherit from this basicFood instance.

Bread.prototype = basicFood; // Bread now inherits from Food.

var bread = new Bread();     // We create some bread!
bread.constructor == Food;  // Though, now we feel very uneasy about how
                           // the constructor is wrong,

Bread.prototype.constructor = Bread; // So we explicitly set the prototype's constructor
bread = new Bread();                // and when we create our new bread,
bread.constructor == Bread;        // we feel much better as the constructor appears correct.

// The issue? Suppose we have another food item, 
 // like in a real inheritance situation:

function Sushi(){};                    // We might be
Sushi.prototype = basicFood;          // tempted to do
Sushi.prototype.constructor = Sushi; // the same thing
var sushi = new Sushi();            // again

sushi.constructor == Sushi;  // Before we realize
bread.constructor == Sushi; // that we've ruined our bread.

basicFood.constructor != Food; // More importantly, we've really ruined all our basicFood,
                              // because while it's a prototype, 
                             // it's also an object in its own right,
                            // and deserves an accurate constructor property.

Who is constructor supposed to really be?

And does constructor have anything to do with the results of instanceof?

I find myself wondering, what is correct? I understand that many would choose to give each food class (Bread, Sushi, etc) a new instance of Food, rather than giving them all the same basicFood instance.. I want this more optimal solution (not making unneeded instances).

Given our Food, Bread, Sushi, and basicFood:

function Food(){}
function Bread(){}
function Sushi(){}
var basicFood = new Food();

I figured I could create an instancing helper, which would define a non-enumerable non-writable non-configurable property 'constructor' on the new instance:

Bread.prototype = basicFood; // We still simply inherit from basicFood
Sushi.prototype = basicFood;


// But we use this helper function when we make instances
function reconstructify(target, Constructor){
  return Object.defineProperty(target, 'constructor', {
    enumerable:   false,
    configurable: false,
    writable:     false,
    value:        Constructor
  });
}

var bread = reconstructify(new Bread(), Bread); // Like so
var sushi = reconstructify(new Sushi(), Sushi);

In testing this, I realized instanceof is not behaving the way I thought it might:

// True expressions for testing -- all good
basicFood.constructor == Food;
bread.constructor     == Bread;
sushi.constructor     == Sushi;

basicFood instanceof Food; // good also
bread instanceof Food;
sushi instanceof Food;

sushi instanceof Bread; // uh oh, not so good that this is true
bread instanceof Sushi; // why is this?

Looking into it more, I can't seem to get instanceof to work the way I'd assume at all:

function Food(){}
function Bread(){}
function Sushi(){}

var basicFood = new Food();

Bread.prototype = basicFood;
Sushi.prototype = basicFood;

var bread = new Bread();
var sushi = new Sushi();

sushi instanceof Bread; // why true?
bread instanceof Sushi; // why true?

I want bread and sushi to both be instances of Food -- not each other.

How can I achieve JavaScript inheritance while maintaining the expected behavior for the constructor property as well as the instanceof operator?

thefourtheye
  • 233,700
  • 52
  • 457
  • 497
ChaseMoskal
  • 7,151
  • 5
  • 37
  • 50
  • Just my personal trash talks, I really do not understand why would people want oo paradigm in JavaScript. To me it's better at functional programming and event driven paradigms. of course mixing in some imperative steps and oo data structure is good, but i find it's rather chaotic to program and maintain if encapsulation or poly morph is involved – miushock Mar 11 '14 at 03:45
  • @miushock: in my particular case, I have a PhotoAlbum class, from which I want FacebookAlbum, GooglePlusAlbum, and ImgurAlbum classes all to inherit from. Could there possibly be a nicer way to do it? Naturally efficient, too! – ChaseMoskal Mar 11 '14 at 03:51
  • The `constructor` property has no explicit purpose in JavaScript. It's at the digression of the developer to make use of it or not. Regarding inheritance, you might want to read [Benefits of using `Object.create` for inheritance](http://stackoverflow.com/q/17392857/218196) – Felix Kling Mar 11 '14 at 04:07
  • @FelixKling: In your more experienced opinion, would it be more logical for me to: **(A)** *Set `F.prototype.constructor=F`* **(B)** *Set `f.constructor=F`* **(C)** *None of the above, totally ignore it and let JavaScript do what it may* -- considering that other developers may use my JavaScript, I would want to leave the most expected `constructor` behavior available to them :) – ChaseMoskal Mar 11 '14 at 04:36
  • **A** would be the way to go. But to truly recreate the default behavior, you'd have to define it as *non-enumerable* via `Object.defineProperty`: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty. Using `F.prototype.constructor = ...` or `f.constructor = ...` would create an *enumerable* property, i.e. it would show up in `for...in` loops. I'd say that this is generally not probably not a problem though, since objects instantiated via constructor functions typically have a specific API to access their data. – Felix Kling Mar 11 '14 at 04:40
  • @FelixKling: interesting yeah, one would want to use defineProperty to make it non-enumerable. Philosophically, I'm not sure what `constructor` is supposed to represent. It could be **(1)** *A property conventional for JavaScript prototypes, which points to the Constructor to which the prototype applies,* or **(2)** *A conventional property for all objects which points to the Constructor who created the object* -- if it's **1**, I'd choose choice **A**, and if it's **2**, I'd choose choice **B**... ...I'm pretty sure it's **1** + **A**, though :) -- Thanks @FelixKling! – ChaseMoskal Mar 11 '14 at 04:51
  • I'm pretty sure it's mostly used as **2**. But all properties that are shared between instances are defined on their prototype anyway. I give you an example where I had to use `constructor`: I'm working on a graph library, where a graph can either be an instance of `Graph`, `DiGraph` (a directed graph), `MultiGraph` (multiple edges between nodes), etc. For some features, I have to create a copy the graph instance. Because `constructor` exists, I can basically do `var h = new g.constructor(); h.add_edges(g.edges); ...`. Without that I'd have to do multiple comparisons with `instanceof` and call – Felix Kling Mar 11 '14 at 05:00
  • the correct constructor function. This might be a special use case, but as soon as you work on more library-ish things, `constructor` can come in handy. – Felix Kling Mar 11 '14 at 05:01
  • @FelixKling: So, the lesson at the end of the day: One prototype object per constructor. Prototype objects aren't really supposed to be shared among different constructors.. ?? – ChaseMoskal Mar 11 '14 at 05:12
  • @FelixKling: If it is **2**, where `constructor` is a conventional property of all objects which points to the function which created the object on which the property lives (in which case, it makes sense that the default constructor for a default prototype is the Constructor which created the default prototype) -- then surely I should be using `defineProperty` to define a non-enumerable `constructor` property directly on the instance itself (not on the prototype). Right? – ChaseMoskal Mar 11 '14 at 05:19
  • I'd say say. The object that `Object.create(...)` returns should only be used with one constructor. I mean, odds are that you want to extend that object with additional methods that the child "class" offers, right? Then all the child "classes" which share the same prototype object would also share all those methods, which is something you probably don't want. Each constructor should have their prototype object. If you are worried about having too many constructors, prototype objects, then maybe a completely different approach would be more appropriate. But that's becoming off-topic now ;) – Felix Kling Mar 11 '14 at 05:19
  • @ChaseMoskal: You can also use `defineProperty` to create that property on the prototype: `Object.definePoperty(Foo.prototpye, ...)`. Rule of thumb: If every instance should have a property with the *same* value as any other instance, that property should live on the prototype. – Felix Kling Mar 11 '14 at 05:21
  • @FelixKling: ***I strongly suspect,*** however, that the case is actually **1**: `constructor` is a conventional property for JavaScript prototypes, which points to the Constructor for which the prototype applies. Evidence for this philosophy can be seen in native JavaScript, with simply: `new String().hasOwnProperty('constructor')` -- it returns `false`, because native JavaScript objects are using `constructor` in form **1** (exclusively on the prototypes) rather than **2** (on all objects including prototypes). – ChaseMoskal Mar 11 '14 at 05:23
  • @FelixKling: I don't really like the `Object.create` methodology, though it's the only which seems to work -- simply because, I don't like creating this weird intermediary between my instances and their inherited methods. ***There must be a better way!*** `bread.eat()` has to check the intermediary prototype first -- `bread.__proto__.eat()`, and doesn't find it there! It's forced to go up an extra level, to `bread.__proto__.__proto__.eat()`... Does this not appear logically problematic to you? – ChaseMoskal Mar 11 '14 at 05:29
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/49446/discussion-between-felix-kling-and-chasemoskal) – Felix Kling Mar 11 '14 at 05:45
  • I'm going to leave this here in case anyone finds it usefull [Implement.js](https://github.com/iamlothian/Implement.js). – Matthew.Lothian Oct 16 '14 at 06:19

4 Answers4

15

Lets examine your code a little bit.

function Food(){}
function Bread(){}
function Sushi(){}
var basicFood = new Food();
Bread.prototype = basicFood;
Sushi.prototype = basicFood;

Note: When you set the same object as the prototype of two objects, augmentation in one prototype, will reflect in the other prototype as well. For example,

Bread.prototype = basicFood;
Sushi.prototype = basicFood;
Bread.prototype.testFunction = function() {
    return true;
}
console.log(Sushi.prototype.testFunction()); // true

Lets get back to your questions.

var bread = reconstructify(new Bread(), Bread);
var sushi = reconstructify(new Sushi(), Sushi);
console.log(sushi instanceof Bread);    // Why true?
console.log(bread instanceof Sushi);    // Why true?

As per the instanceof docs from MDN,

The instanceof operator tests whether an object has in its prototype chain the prototype property of a constructor.

So when we do something like

object1 instanceof object2

JavaScript will try to find if the prototype of the object2 is in the prototype chain of object1.

In this case, it will return true only when the Bread.prototype is in the prototype chain of sushi. We know that sushi is constructed from Sushi. So, it will take Sushi's prototype and check if it is equal to Bread's prototype. Since, they both point to the same basicFood object, that returns true. Same case for, bread instanceof Sushi as well.

So, the right way to inherit would be, like this

function Food()  {}
function Bread() {}
function Sushi() {}

Bread.prototype = Object.create(Food.prototype);
Bread.prototype.constructor = Bread;
Sushi.prototype = Object.create(Food.prototype);
Sushi.prototype.constructor = Sushi;

var bread = new Bread();
var sushi = new Sushi();

console.log(sushi instanceof Bread);  // false
console.log(bread instanceof Sushi);  // false
console.log(sushi.constructor);       // [Function: Sushi]
console.log(bread.constructor);       // [Function: Bread]
console.log(sushi instanceof Food);   // true
console.log(bread instanceof Food);   // true
console.log(sushi instanceof Sushi);  // true
console.log(bread instanceof Bread);  // true
thefourtheye
  • 233,700
  • 52
  • 457
  • 497
  • 1
    please stop using Object.create and use the `new` keyword. – helly0d Mar 11 '14 at 03:50
  • http://stackoverflow.com/questions/13040684/javascript-inheritance-object-create-vs-new – helly0d Mar 11 '14 at 03:53
  • And also because of some downfalls in earlier browsers, and also because this would be the native way to do it. – helly0d Mar 11 '14 at 03:54
  • @helly0d: Nope, using the `new` keyword to establish inheritance is not a good idea: http://stackoverflow.com/a/17393153/218196 – Felix Kling Mar 11 '14 at 04:04
  • @thefourtheye: The deal-breaker for this technique is the same as for the other answer. Here, you are creating unnecessary instances, which defeats the purpose of using prototypical inheritance to begin with. This is about re-using code, and when we're re-instancing many copies of the same thing, we're throwing the performance out the window. – ChaseMoskal Mar 11 '14 at 04:05
  • 1
    @FelixKling and yet `Object.create` still uses the `new` keyword inside of it. I really love the logic. STOP USING Object Oriented approach in JS ! – helly0d Mar 11 '14 at 04:07
  • 1
    @helly0d: I assume you haven't read my post properly. Sorry for my vague statement. I should have said: *"Don't create a new instance of the super class to establish inheritance"*. And what does this have to do with OO? JavaScript is full of objects! – Felix Kling Mar 11 '14 at 04:09
  • @FelixKling Please do not judge too fast. I know what you are trying to say, and even if JS is full of Objects, the power of the code is not coming from the `prototype` chain, but from the fact that in this language we have only Objects and not a single class. Don't try to copy and paste the code from Java in JavaScript and make it flawless. And by the way Object.create does a new instance for you. – helly0d Mar 11 '14 at 04:13
  • @ChaseMoskal please check the part in my answer where I explain why using the same object as the prototype for two different functions, is a disaster. – thefourtheye Mar 11 '14 at 04:13
  • To correct myself, I see you're actually creating a new intermediary object which itself inherits from Food. What I'd want would be closer to `Bread.prototype = Object.create(basicFood);` more like -- which may indeed hit the mark...` – ChaseMoskal Mar 11 '14 at 04:13
  • 1
    @helly0d: It creates an object that inherits from whatever value you pass to the function. But it does not call the constructor function, and that's the important part. Of course if we defined an instance as "inherits from the specific prototype", then you are right, it does create an instance. Also, it's been years since I touched Java, so maybe you should not judge so quickly. And I still fail to see why using `Object.create` should be more "Java-ish" than `new Foo`. – Felix Kling Mar 11 '14 at 04:15
  • @FelixKling I am going to stop this useless debate. There will always be 2 gangs of JS programmers. We will have much more fun with ES6 after they will add the actual `class` functionality. – helly0d Mar 11 '14 at 04:17
  • *[ edit: my questions were answered by the answerer's edits :) ]* – ChaseMoskal Mar 11 '14 at 04:19
  • 1
    @helly0d If I were you I ll listen, try to understand what Felix says and would consider this as a worthy discussion. He has more knowledge than all of us here :) – thefourtheye Mar 11 '14 at 04:19
  • @helly0d: I still want to understand why you think using `Object.create` would be applying Java style coding to JavaScript. Do you think that making use of prototypal inheritance is wrong? Also, the class syntax in JS is just syntactic sugar, it doesn't change anything about how JS works internally. – Felix Kling Mar 11 '14 at 04:20
  • @helly0d: isn't Object.create basically just a shortcut for: `function create(x){ function X(){}; X.prototype=x; return new X }`?? – ChaseMoskal Mar 11 '14 at 04:21
  • @ChaseMoskal—no. That pattern creates an extra function object and calls it as a constructor. *Object.create* just creates a new object and sets its `[[Prototype]]` to the required value, similar to `var o = {}; o.__proto__ = x;`. – RobG Mar 11 '14 at 04:29
  • 2
    @thefourtheye: Thanks for the compliment btw! I'd never claim something like this about myself, but some recognition feels good :) You are not doing such a bad job yourself! Keep up the good work :) – Felix Kling Mar 11 '14 at 04:48
  • @FelixKling wrote: *"""@helly0d: I still want to understand why you think using Object.create would be applying Java style coding to JavaScript"""* -- Funny, [here](http://javascript.crockford.com/prototypal.html) Crockford wrote the opposite: *"""This indirection [the `new` operator] was intended to make the language seem more familiar to classically trained programmers, but failed to do that, as we can see from the very low opinion Java programmers have of JavaScript."""* – ChaseMoskal Mar 11 '14 at 05:07
  • @AariaCarterWeir Well, after 1 year and a half, I can say I am sorry for the mess I have caused here; I was young and stupid. Yes, FelixKling was right and I apologize for how stupid and arrogant I was. – helly0d Dec 27 '15 at 12:13
  • @helly0d haha chill. life is all about learning, god knows how many time ive made worse mistakes. happy new year dude :) – Aaria Carter-Weir Jan 06 '16 at 00:37
  • hehe, very interesting discussion. @helly0d, it's great that you are so honest and come back and apologize! And as ariana-carter-weir, we all make mistakes while learning.... and are ashamed for our old code :-S :) – K.S. Jul 10 '17 at 08:14
4

Your only problem in your logic was setting the same object basicFood to both Bread.prototype and Sushi.prototype. Try to do something like this:

Bread.prototype = new Food();
Bread.prototype.constructor = Bread;

Sushi.prototype = new Food();
Sushi.prototype.constructor = Sushi;

Now the instanceof bread and sushi will be Food but the constructors will be Bread and Sushi for each of them in particular;

helly0d
  • 828
  • 2
  • 10
  • 27
  • *The deal-breaker with this technique, is that it's unnecessarily creating extra Food instances.* I specifically want to create only one basicFood instance from which all foods will inherit -- the beauty in that design, is first that you can unanimously modify every food item's prototype properties with that one basicFood instance, and second, that you are not creating many wasteful instances where only one is needed (consuming memory, perhaps a CPU-intensive construction process). – ChaseMoskal Mar 11 '14 at 03:56
  • For my concerns, the performance rationale there far outweighs the need to unanimously modify all food items – ChaseMoskal Mar 11 '14 at 04:01
  • In here i am sorry to inform you but you are wrong. To inherit from an object to another you have to create an instance of that Class to be able to get the entire prototype chain. So each child class has to get the property chain copied from an actual instance. Also the CPU problem occurs for the creation of over 100000 objects in the same time. If you want to improve try not to relay on OO approach in JS and try a more optimal solution, like having the collection of the methods in one place and changing the scope using apply and bind. Also a.prototype has become 10 times slower. – helly0d Mar 11 '14 at 04:02
  • the prototype chain, as i was saying has become 10 times slower than the native one ( declaring methods inside the class scope -- `this.method = function(){}` -- ) – helly0d Mar 11 '14 at 04:03
  • *"To inherit from an object to another you have to create an instance of that Class to be able to get the entire prototype chain"* That's where you are wrong, and that's what `Object.create` solves. – Felix Kling Mar 11 '14 at 04:11
  • *"the prototype chain, as i was saying has become 10 times slower than the native one"* Such statements are worthless without references. – Felix Kling Mar 11 '14 at 04:14
  • @FelixKling, I look for you for clarification: So, then, I'm gathering, I'm still right about the fact that *this particular answer is unoptimal,* as it stands, because it's actually fully instancing (running constructors and all) an excessive number of times, and is creating an excessive number of instances. It sounds to me, like `Object.create` allows us to create an intermediary object to serve as the prototype, which itself inherits (doesn't instance) methods from the parent constructor, so as not to waste resources unnecessarily. Yeah? – ChaseMoskal Mar 11 '14 at 04:30
  • 1
    @ChaseMoskal: To be honest, I haven't read your whole post, but to answer your comment: Whether you use `new ...` or `Object.create(...)`, you will generate the same amount of objects. It's true that `Object.create` doesn't run the constructor function, so that is what you "safe". Whether that has any impact on run time or memory depends on what you are actually doing in the constructor. My opinion is more from a conceptional viewpoint: Using `Object.create` feels right because all you want is hook up the parents prototype in the children's prototype chain. – Felix Kling Mar 11 '14 at 04:38
  • @ChaseMoskal: You don't actually want to create a "true" instance of the parent class. – Felix Kling Mar 11 '14 at 04:39
  • @FelixKling: Which is what @helly0d's answer does, with `Bread.prototype = new Food()` and such -- making this particular answer unoptimal :) – ChaseMoskal Mar 11 '14 at 04:42
  • I have struggle with the quirks to understand how to do this properly. Either use Object.create or new; and even if you use Object.create to create new 'instances' of a particular type , anyway you need to use new- http://alexpunnen.blogspot.in/2014/02/javascript-prototypal-inheritance-with.html ( I am not a language surgeon but this is my understanding) – Alex Punnen Mar 11 '14 at 04:44
  • So, after everything I've learned.. @helly0d's answer, was totally correct all along: *"""[helly0d:] Your only problem in your logic was setting the same object basicFood to both Bread.prototype and Sushi.prototype."""* -- The code in helly0d's answer is actually the simplest in this thread, although it is less optimal from a performance perspective. – ChaseMoskal Mar 11 '14 at 06:51
3

This is my personal solution, which I have developed from the combined wisdom nuggets of @thefourtheye, @FelixKling, @SeanKinsey, and even the antics of @helly0d:


Simplest Solution:

/** Food Class -- You can bite all foods **/
function Food(){ this.bites = 0 };
Food.prototype.bite = function(){ console.log("Yum!"); return this.bites += 1 };

/** All Foods inherit from basicFood **/
var basicFood = new Food();

/** Bread inherits from basicFood, and can go stale **/
function Bread(){
  Food.apply(this); // running food's constructor (defines bites)
  this.stale = false;
};
Bread.prototype = Object.create( basicFood );
Bread.prototype.constructor = Bread; // just conventional
Bread.prototype.goStale = function(){ return this.stale = true };

/** Sushi inherits from basicFood, and can be cooked **/
function Sushi(){
  Food.apply(this);
  this.raw = true;
};
Sushi.prototype = Object.create( basicFood );
Sushi.prototype.constructor = Sushi;
Sushi.prototype.cook = function(){ return this.raw = false };



Advanced Methodology:

It's better because it makes the constructor prototype property a non-enumerable.

/** My handy-dandy extend().to() function **/
function extend(source){
  return {to:function(Constructor){
    Constructor.prototype = Object.create(source);
    Object.defineProperty(Constructor.prototype, 'constructor', {
      enumerable:   false,
      configurable: false,
      writable:     false,
      value:        Constructor
    });
    return Constructor;
  }}
};


function Food(){ this.bites = 0 };
Food.prototype.bite = function(){ console.log("Yum!"); return this.bites += 1 };
var basicFood = new Food();


var Bread = extend(basicFood).to(function Bread(){
  Food.apply(this);
  this.stale = false;
});
Bread.prototype.goStale = function(){ return this.stale = true };


var Sushi = extend(basicFood).to(function Sushi(){
  Food.apply(this);
  this.raw = true;
});
Sushi.prototype.cook = function(){ return this.raw = false };



Both methodologies above yield the same test results:

var food  = new Food();
var bread = new Bread();
var sushi = new Sushi();

console.log( food instanceof Food );   // true
console.log( food instanceof Bread );  // false
console.log( food instanceof Sushi );  // false

console.log( bread instanceof Food );  // true
console.log( bread instanceof Bread ); // true
console.log( bread instanceof Sushi ); // false

console.log( sushi instanceof Food );  // true
console.log( sushi instanceof Bread ); // false
console.log( sushi instanceof Sushi ); // true

console.log( food.constructor );       // Food
console.log( bread.constructor );      // Bread
console.log( sushi.constructor );      // Sushi



A very special thanks to @FelixKling, whose experience helped hone my understanding in the chat outside of this thread -- also to @thefourtheye, who was the first to show me the correct way -- and also to @SeanKinsey, who highlighted the usefulness of being able to run the parent constructor within the context of the children.

I community wiki'd this answer -- please let me know or edit yourself if you find anything in this answer's code which is suspect :)

ChaseMoskal
  • 7,151
  • 5
  • 37
  • 50
  • `Object.create` hides away most of the actual logic here though (return an object with a prototype set to `basicFood`), so it would be better if you showed this with actual ES3 JavaScript. – Sean Kinsey Mar 11 '14 at 07:07
1

What you are doing wrong is to reuse the basicFood object for multiple child 'classes'. Instead, new up a new one. That way, as you add members to the prototype (new instance of the parent), you're adding it to an instance that is not shared among other inheriting classes.

Now, there's one thing that your code is lacking, and that is constructors without side effects. Many constructors requires arguments, and will throw without them - but how can you construct a prototype for a new descending class without new'ing up a parent? Well, we're not actually interested in the parent function, only in the parents prototype. So what you can do is

function Parent() { /*some side effect or invariant */ }
Parent.prototype.foo = ...
function Child() { Parent.call(this); }

// the next few lines typically go into a utility function
function F() {} // a throw-away constructor
F.prototype = Parent.prototype; // borrow the real parent prototype
F.prototype.constructor = Parent; // yep, we're faking it
Child.prototype = new F(); // no side effects, but we have a valid prototype chain
Child.prototype.bar = ... // now continue adding to the new prototype
Sean Kinsey
  • 37,689
  • 7
  • 52
  • 71
  • *"""That way, as you add members to the prototype (new instance of the parent), you're adding it to an instance that is not shared among other inheriting classes."""* **<--- Isn't that the opposite of what I want?** I want to reuse as many methods as possible, and instance as few as possible. – ChaseMoskal Mar 11 '14 at 05:34
  • "other inheriting classes", the instances of one class all share the prototype, but as you have multiple descending classes, each gets their own prototype object – Sean Kinsey Mar 11 '14 at 06:20
  • Right, I see what you mean now -- if `ChildAlpha.prototype = parentInstance`, we're going to have a bad time setting any properties to `ChildAlpha.prototype` without screwing up `ChildBravo`, if the children share a prototype. I suppose, it's that I wasn't planning to do such a thing -- I literally wanted the prototype (every single property there) to be shared, which I suppose is ideologically fine on its own, but JavaScript (specifically, `instanceof`) isn't prepared to handle those kinds of minimalistic relationships, and assumes the fuller, more flexible architecture you demonstrated. – ChaseMoskal Mar 11 '14 at 06:44
  • Your problem was probably that since you shared a prototype, you couldn't set .constructor on `ChildBravo.prototype` without destroying the one you set on `ChildAlpha.prototype`. Prototypes are meant to be shared among instances of the same type, and in your case, it seems like you you wanted identical types, but different instanceof checks? – Sean Kinsey Mar 11 '14 at 07:04