Here’s the biggest problem with your examples, which are emphatically *NOT* using prototype chaining…
function Foo() { this.getFoo = function(){ return ‘foo’; }; }
new Foo().getFoo === new Foo().getFoo; // false
When you use this.foo = function…, you’re creating a new function and attaching it to the instance… When you use Foo.prototype.foo, it is a function bound to the instance’s inheritance chain and calls the same function.
The function itself is not the same function between instances. Also, the search path will work up the stack. You can either set a constructor function to inherit from an instance, or Object.create(Parent.prototype);
Bar.prototype.getValue = function() { return Math.random(); }
function Foo() {
Bar.call(this);
}
new Foo().getValue(); // Uncaught TypeError: (intermediate value).getValue is not a function
you need to bind to the prototype….
Foo.prototype = Object.create(Bar.prototype);
— —
Another issue missed is that the prototype based inheritance chain is a search chain… ex: if you have Foo that inherits from Bar that inherits from Baz with inherits from FooBar … What happens when you call new Foo().prop is that the engine will see if there is “prop” on the instance, then instance’s prototype, then the parent prototype and so on. This is fairly slow if you go more than 1–2 layers deep, which means multiple points of inheritance in JS is pretty bad if used a lot. At that point it’s better to just attach the nested inheritance methods and/or attach directly in the constructor as the replicated cost in memory is better than the search cost in performance.
Foo.prototype ={…FooBar.prototype, …Baz.prototype, …Bar.prototype};
Of course this will *not* support (new Foo() instanceof FooBar) for type/inheritance checking.