1. Prototype chain inheritance: The relationship between constructors, prototypes and instances: Each constructor has a prototype object, and the prototype object contains a pointer to the constructor , and instances contain an internal pointer to the prototype object. Use instanceof to confirm the relationship between prototype and instance.
Disadvantages of prototype chain inheritance: literal overriding of the prototype will break the relationship, use the prototype of the reference type, and the subtype cannot pass parameters to the supertype
function Parent(){ this.name='mike'; } function Child(){ this.age=12; } //儿子继承父亲(原型链) Child.prototype=new Parent();//Child继承Parent,通过原型形成链条 var test=new Child(); console.log(test.age); console.log(test.name);//得到被继承的属性 //孙子继续原型链继承儿子 function Brother(){ this.weight=60; } Brother.prototype=new Child();//继承原型链继承 var brother=new Brother(); console.log(brother.name);//继承了Parent和Child,弹出mike console.log(brother.age);//12 console.log(brother instanceof Child);//ture console.log(brother instanceof Parent);//ture console.log(brother instanceof Object);//ture
2. Constructor implements inheritance: It is also called fake object or classic inheritance.
Disadvantages of constructor implementation inheritance: Although borrowing constructors solves the two problems of prototype chain inheritance, without a prototype, reuse is impossible, so the prototype chain + borrowed constructor pattern is needed.
function Parent(age){ this.name=['mike','jack','smith']; this.age=age; } function Child(age){ Parent.call(this,age);//把this指向Parent,同时还可以传递参数 } var test=new Child(21); console.log(test.age);//21 console.log(test.name); test.name.push('bill'); console.log(test.name);//mike,jack,smith,bill
3. Combination inheritance: Use the prototype chain to inherit prototype properties and methods, and borrow constructors to achieve inheritance of instance properties. In this way, function reuse is achieved by defining methods on the prototype, and each implementation is guaranteed to have its own attributes.
Disadvantages: In any case, the supertype constructor will be called twice, once when creating the subtype prototype, once when creating the subtype prototype, and once inside the subtype constructor.
function Parent(age){ this.name=['mike','jack','smith']; this.age=age; } Parent.prototype.run=function(){ return this.name+' are both '+this.age; } function Child(age){ Parent.call(this,age);//给超类型传参,第二次调用 } Child.prototype=new Parent();//原型链继承,第一次调用 var test1=new Child(21);//写new Parent(21)也行 console.log(test1.run());//mike,jack,smith are both 21 var test2=new Child(22); console.log(test2.age); console.log(test1.age); console.log(test2.run()); //这样可以使test1和test2分别拥有自己的属性age同时又可以有run方法
4. Prototypal inheritance: Using prototypes, you can create new objects based on existing objects without having to create custom types. It requires that there must be an object that can serve as the basis for another object.
function object(o){ function F(){}; F.prototype=o; return new F(); } var person={ name:'nicho', friends:['shell','jim','lucy'] } var anotherPerson = object(person); anotherPerson.name = 'Greg'; anotherPerson.friends.push('Rob'); console.log(anotherPerson.friends);//["shell", "jim", "lucy", "Rob"] var yetAnotherPerson = object(person); yetAnotherPerson.name = 'Linda'; yetAnotherPerson.friends.push('Barbie'); console.log(yetAnotherPerson.friends);//["shell", "jim", "lucy", "Rob", "Barbie"] console.log(person.friends);//["shell", "jim", "lucy", "Rob", "Barbie"]
ECMAScript5 standardizes prototypal inheritance through the new Object.create() method, which accepts two parameters: an object used as the prototype of the new object and (optional) an object that defines properties for the new object.
var person2={ name:'nicho', friends:['shell','jim','lucy'] }; var anoP2=Object.create(person2); anoP2.name="Greg"; anoP2.friends.push('Rob'); console.log(anoP2.friends);//["shell", "jim", "lucy", "Rob"] var yetP2=Object.create(person2); yetP2.name="Linda"; yetP2.friends.push('Barbie'); console.log(yetP2.friends);//["shell", "jim", "lucy", "Rob", "Barbie"] console.log(person2.friends);//["shell", "jim", "lucy", "Rob", "Barbie"] /*以这种方式指定的任何属性都会覆盖原型对象上的同名属性。*/ var threeP=Object.create(person,{ name:{value:'red'} }); console.log(threeP.name);//red,如果threeP中无name则输出person2里的name值nicho
5. Parasitic inheritance: The idea is similar to the parasitic constructor and factory pattern, that is, creating a function that is only used to encapsulate the inheritance process, and the function is used internally in some way. way to enhance the object, and finally return the object as if it really did all the work.
function object(o){ function F(){}; F.prototype=o; return new F(); }; function createAnother(o){ var cl=object(o); cl.sayHi=function(){ console.log('hi'); } return cl; }; var person={ name:'nick', friends:['shelby','court','van'] } var anotherPerson=createAnother(person); anotherPerson.sayHi();//hi console.log(anotherPerson.name);//nick console.log(anotherPerson.friends);//["shelby", "court", "van"] /*这个例子中的代码基于 person 返回了一个新对象—— anotherPerson 。 新对象不仅具有 person 的所有属性和方法,而且还有自己的 sayHi() 方法*/
Parasitic combined inheritance: No matter what the circumstances, the supertype constructor will be called twice, once when creating the subtype prototype, once when creating the subtype prototype, and once during the subtype construction. function, so that the subtype ends up containing all instance properties of the supertype object, which we have to override when calling the subtype constructor. Hence the emergence of parasitic combinatorial inheritance.
6. Parasitic combined inheritance: Borrow constructors to inherit properties, and inherit methods through the mixed form of the prototype chain. Basic idea: You don't have to call the supertype's constructor in order to specify the subtype's prototype. Essentially, parasitic inheritance is used to inherit the prototype of the supertype, and then assign the result to the prototype of the subtype.
function SuperType(name){ this.name=name; this.colors=['red','blue','green']; } SuperType.prototype.sayName=function(){ console.log(this.name); } function SubType(name,age){ SuperType.call(this,name); this.age=age; } function object(o){ function F(){}; F.prototype=o; return new F(); }; /*inheritPrototype此函数第一步是创建超类型原型的一个副本。第二步是为创建的副本添加constructor属性, * 从而弥补因重写原型而失去的默认的constructor属性,第三步将新创建的对象(副本)赋值给子类型的原型*/ function inheritPrototype(subType,superType){ var prototype=object(superType.prototype);//创建对象 prototype.constructor=subType;//增强对象 subType.prototype=prototype;//指定对象 } inheritPrototype(SubType,SuperType); SubType.prototype.sayAge=function(){ console.log(this.age); } var p=new SubType('xiaoli',24); console.log(p.sayName()); console.log(p.sayAge()); console.log(p.colors)
Advantages of this method: The parent class SuperType constructor is only called once, and therefore avoids creating unnecessary redundant attributes on SubType.prototype. At the same time, the prototype chain can remain unchanged, and instanceof and isPrototypeOf() can be used normally;
The above introduction to several JavaScript inheritance methods is all the content shared by the editor. I hope it can give you a reference, and I hope you will support Script Home.