Javascript: Question re prototpyes

Why would I want to use Object.create() when I can just assign one object’s prototype to another object’s prototype?

function Thingy() {}
Thingy.prototype.change = function () {
  return this.char1 + this.char2;
}
function Thingamajig(param1, param2) {
  this.char1 = param1;
  this.char2 = param2;
}
Thingamajig.prototype = Thingy.prototype;

var thingy1 = new Thingy();
var thingamajig1 = new Thingamajig(1, 2);

alert(thingamajig1.change());//3

Thanks in advance.

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:

3 Likes

Thanks for your reply. For my purpose, I am using an old environment which does not support ES6, so I am forced to use the outdated ways. Thanks again.

You can use BabelJS.io to convert modern JS to old JS when you’re ready to deploy it: :bulb:

1 Like