Your posted example above is about classical (I’d say archaic) inheritance.
For more than half a decade already the modern way of doing that is via keywords class
, extends
and super
:
Below’s your sketch rewritten to use modern inheritance:
'use strict';
class Thingy {
change() {
return this.char1 + this.char2;
}
}
class Thingamajig extends Thingy {
constructor(param1, param2) {
super();
this.char1 = param1;
this.char2 = param2;
}
}
const thingy1 = new Thingy(),
thingamajig1 = new Thingamajig(1, 2);
alert(thingamajig1.change()); // 3
Back to your classical inheritance example, why is Thingamajig.prototype = Thingy.prototype;
wrong?
B/c you don’t add anything to Thingamajig, your sketch works w/o any glitches.
But the moment you decide to add any new methods to Thingamajig you will notice those would show up on Thingy as well.
B/c both Thingy & Thingamajig are sharing the same object prototype{}.
So instead of assigning Thingy.prototype{} to Thingamajig.prototype{} you would want a clone of the former.
That’s where Object.create() comes in:
Thingamajig.prototype = Object.create(Thingy.prototype);
This time we’re assigning a clone of Thingy.prototype{} to Thingamajig.prototype{}.
So they’re not alias to the same prototype{} object anymore.
And thus we can make changes to Thingamajig.prototype{} w/o having those reflected back to Thingy.prototype{}.
However, we’ve got 1 more detail to deal w/.
Due to Thingamajig.prototype{} reassignment, we end up losing its original prototype{}.constructor() function:
And instead it points to Thingy constructor function.
In order to amend that, we need to reassign that back to Thingamajig:
Thingamajig.prototype.constructor = Thingamajig;
So we actually need 2 steps for a correctly classical inheritance:
Thingamajig.prototype = Object.create(Thingy.prototype);
Thingamajig.prototype.constructor = Thingamajig;
P.S.: Object.create() doesn’t actually clone an object, but rather creates an empty 1 w/ its __proto__
pointing to the 1st passed object parameter: