Search code examples
javascriptecmascript-5prototypal-inheritance

Why was surrogate class needed in JavaScript ES5 prototypal inheritance?


I have a pretty good understanding of JavaScript's prototypal inheritance but I wouldn't say it's perfect. I am looking at the latest prototypal syntax for JavaScript inheritance and so far it makes pretty good sense.

__proto__ is used for looking up parent function's prototype. Say I have Cat and Mammal, I can simply point Cat.prototype.__proto__ to Mammal.prototype.

ChildClass.prototype.__proto__ = ParentClass.prototype;
ChildClass.prototype.constructor = ChildClass;

The use of __proto__ was strongly discouraged because it was not standardized only until recently. Thus, the modern standardized practice is to use Object.create

ChildClass.prototype = Object.create(ParentClass.prototype);
ChildClass.prototype.constructor = ChildClass;

Now let's look at ES5's surrogate approach

function Surrogate() {};
Surrogate.prototype = ParentClass.prototype;
ChildClass.prototype = new Surrogate();
ChildClass.prototype.constructor = ChildClass;

Obviously,

ChildClass.prototype = ParentClass.prototype;

is bad, because modifying ChildClass's prototype will also modify ParentClass's prototype.

But why can't we do this?

ChildClass.prototype = new ParentClass();

Why do we need a surrogate in between?


Solution

  • But why can't we do this?

    ChildClass.prototype = new ParentClass();

    How do you know that calling ParentClass constructor w/o arguments would not throw an error?

    Imagine ParentClass was implemented this way.

    function ParentClass(name) {
      if(!name) throw new Error('name is required');
    
      this.name = name;
    }