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