Inheritance in js

Keywords: Javascript

ES5 implementation inheritance

Declare a Person object as the parent, and the child cPerson will inherit all the properties and methods of Person.

function Person(name, age) {
    this.name = name;
    this.age = age;
}

Person.prototype.getName = function() {
    return this.name;
}

Constructor inheritance

With the help of the call method, the constructor of the parent is executed once, which is equivalent to copying the code in Person in cPerson, where this points to the instance object new from Student. The call method ensures the correct direction of this, so it is equivalent to inheritance.
Disadvantages: even if the instance object has the same method, constructor inheritance will create a separate method for each instance object, wasting memory.

// Constructor inheritance
function cPerson(name, age, job) {
    Person.call(this, name, age);
    this.job = job;
}

Prototype inheritance

// Inheritance prototype
cPerson.prototype = new Person(name, age)

// Add more methods
cPerson.prototype.getLive = function() {}

Disadvantages: attributes in prototype inheritance are shared. If an instance object modifies an attribute, another instance object will obtain the modified attribute value.

Combinatorial inheritance

In order to solve the shortcomings of the above structural inheritance and prototype inheritance, composite inheritance appears. Generally, the properties that are not shared are inherited through construction, but the methods that need to be shared are inherited through prototype.
Disadvantages: composite inheritance will call the code of the parent constructor twice

function Person(name){
  this.name=name;
}
Person.prototype.sayName=function(){
  console.log(this.name+' '+this.gender+' '+this.age);
}
function Female(name,gender,age){
  Person.call(this,name);//The first call to the parent constructor             
  this.age=age;
  this.gender=gender;
}
Female.prototype=new Person();//Call the parent constructor the second time
Female.prototype.constrcutor=Female;//The constructor attribute is lost due to rewriting the prototype, so the constructor needs to be re assigned

Parasitic combinatorial inheritance

It inherits properties by borrowing constructors and inherits methods through prototype chains. It does not need to specify prototypes for subclasses and call the constructor of the parent class, eliminating the above steps of calling the constructor of the parent class for the second time.

By creating a copy of the prototype of the parent class, adding a constructor to it, and finally assigning a value to the prototype of the child class. This avoids calling the constructor of the parent class twice and creating redundant properties for it

function inheritPrototype(Female,Person){ 
  var protoType=Object.create(Person.prototype);
  protoType.constructor=Female;
  Female.prototype=protoType;
}
inheritPrototype(Female,Person);
Female.prototype.sayAge=function(){
	console.log(this.name+' '+this.age);
}
//replace
//Female.prototype=new Person();
//Female.prototype.constrcutor=Female

//The above code is equivalent to:
Female.prototype = Object.create(Person.prototype, {
    constructor: {     //Reassign constructor
        value: Student
    }
    sayAge: {
        value: function() {
            return this.grade //Add new method
        }
    }
})

 var fm=new Female('skila','female',19);
 fm.sayName();//skila female 19
 fm.sayAge();skila  19
Object.create()

Create a new object and use the existing object to provide the information of the new object created__ proto__

function create(proto, options) {
    // Create an empty object
    var tmp = {};

    // Make this new empty object an instance of the parent object
    tmp.__proto__ = proto;

    // The incoming methods are mounted on the new object, which will be the prototype of the subclass object
    Object.defineProperties(tmp, options);
    return tmp;
}
Object.defineProperties()
var obj = {};
Object.defineProperties(obj, {
  'property1': {
    value: true,
    writable: true
  },
  'property2': {
    value: 'Hello',
    writable: false
  }
  // etc. etc.
})

ES6 implementation inheritance

class Person{
  constructor(name,age){
    //this here refers to the instance object
    this.name = name
    this.age = age
  }
  //say bind to Person.prototype
  say(){
    console.log('my name is ' + this.name + ", I am " + this.age)
  }
  //sayHobby is bound to Person.prototype
  sayHobby(){
    console.log('no hobby')
  }
  //sayName bound to instance object
  sayName = function(){
    console.log('my name is ' + this.name)
  }
  //sayAge bind to instance object
  sayAge = () => {
    console.log('I am ' + this.age + ' years old')
  }
}
//Extensions implements inheritance
class cPerson extends Person{
  constructor(name, age, hobby){
    super(name, age)
    this.hobby = hobby
  }
  sayHobby = function(){
    console.log('I like ' + this.hobby )
  }
}
const p = new cPerson('zs', 12, 'drawing')
console.log(p.name)  //zs
console.log(p.age)  //12
console.log(p.hobby)  //drawing
p.say() //my name is zs, I am 12
p.sayName() //my name is zs
p.sayHobby() //I like drawing
//Properties on instance objects can be deleted
delete p.sayHobby
p.sayHobby() //Will look up through the prototype chain

Posted by DwarV on Mon, 27 Sep 2021 22:16:29 -0700