Polyfill for extend in JavaScript

Write a simple polyfill for the extends method. Create a simple function that will accept the two functions parent and child and extend the child function to have all parent properties.

Example

function Parent() {
  this.name = "abc";
};

Parent.prototype.walk = function(){
  console.log (this.name + ', I am walking!');
};

function Child() {
  this.name = "pqr";
};

Child.prototype.sayHello = function(){
  console.log('hi, I am a student');
};

// function to extend 
extend(Parent, Child);

const child = new Child();
child.sayHello();
child.walk();

console.log(child instanceof Parent); 
console.log(child instanceof Child);

Output:
"hi, I am a student"
"pqr, I am walking!"
true
true

To extend a child from a parent, we must copy all the static and non-static methods of the complete prototype chain.

And for this, we can either update the reference of the child’s prototype to point to the parent or use the Object.setPrototypeOf(child, parent) to create the link.

Here I have used one method for extending and commented on the second. You can choose between either based on your preference.

const myExtends = (SuperType, SubType) => {
  // extend the child to point to the parent
  // all the nonstatic methods
  SubType.prototype.__proto__ = SuperType.prototype;
  //ES5: Object.setPrototypeOf(SubType.prototype, SuperType.prototype);

  // static methods;
  SubType.__proto__ = SuperType;
  //ES5: Object.setPrototypeOf(SubType, SuperType);
  
  // as the child is pointing to the parent
  // after it, update the child's constructor to point itself.
  SubType.prototype.constructor = SubType;
  //ES5: Object.setPrototypeOf(SubType.prototype, SubType.prototype);
}
Input:
// Parent
function Person() {
  this.name = "abc";
}

// non static methods
Person.prototype.walk = function(){
  console.log (this.name + ', I am walking!');
};

Person.prototype.sayHello = function(){
  console.log ('hello');
};

// static methods
Person.staticSuper = function(){
  console.log('static');
};

// child
function Student() {
  this.name = "pqr";
}

// sayHello
// this will replace the parent after extending
Student.prototype.sayHello = function(){
  console.log('hi, I am a student');
}

// add sayGoodBye method
Student.prototype.sayGoodBye = function(){
  console.log('goodBye');
}

const Extend = myExtends(Person, Student);

const student1 = new Student();
student1.sayHello();
student1.walk();
student1.sayGoodBye();
Student.staticSuper();
console.log(student1.name);

// check inheritance
console.log(student1 instanceof Person);
console.log(student1 instanceof Student);

Output:
"hi, I am a student"
"pqr, I am walking!"
"goodBye"
"static"
"pqr"

true
true