Patrick Desjardins Blog
Patrick Desjardins picture from a conference

JavaScript Prototype Part 5 : Inheritance without "new" (Prototypal Approach)

Posted on: 2017-06-06

There is so many different ways to do something in JavaScript that become overwhelming to know which one to use. In this article, we will a different way to create multiple instances of an object with a base class without using the keyword "new". If you want to see, how to use "new", you can see that past article about how to create inheritance with JavaScript.

Let's create a simple literal object that define a member and a function.

let baseClass1 = {
  memberbase: "base",
  functionbase() {
    return (
      "This is memberbase value (" +
      this.memberbase +
      ") with access to the child value (" +
      this.memberchild +
      ")"
    );
  },
};

The child class, that will inherit the base class, needs to be dynamically called and return a new instance every time invoked. To do so, without using "new", we need to use two Object methods. The first one is Object.assign which extends the base class with the child literal object. The second one is Object.create which create the hierarchy with the prototype.

let childClass1 = function childFactory() {
  return Object.assign(Object.create(baseClass1), { memberchild: "child" });
};

To consume this creation pattern, we only need to call the childClass1 function.

let instance1 = childClass1();
let instance2 = childClass1();
instance2.memberchild = "child 2";

console.log(instance1.memberchild); // child
console.log(instance2.memberchild); // child 2
console.log(instance1.functionbase()); // This is memberbase value (base) with access to the child value (child)
console.log(instance2.functionbase()); // This is memberbase value (base) with access to the child value (child 2)

This works, like working with the new pattern. The difference is that we are not calling the base class from the child constructor, but instead having a factory that use assign and create. While we were using Object.create to assign the prototype of the child to match up the base one with the "new" pattern, in that case we touch the prototype because Object.create first parameter is to assign the prototype.

The reason is that we are using assign to merge the two literal objects into a single one -- there is not need to play with "real" hierarchy. Finally, we do not need to set the constructor of the child class, because we do not instantiate with the keyword new.