Prototype chain
Usage: Give the parent class of the instance to the child class (the prototype of the child function).
Disadvantages: because obj2.arr also changes after modifying obj1arr, because the instance is shared in the reference attribute from the prototype object.
2> When creating a subclass instance, the parent class constructor cannot pass parameters.
//父亲函数
function Parent(){
this.userName="父亲函数";
this.arr=[1,2,3];
}
//子函数
function Child(){
this.age=18;
}
//对象实例赋值是引用类型
Child.prototype=new Parent();
var obj1=new Child();
var obj2=new Child();
// 由于是引用类型,改一个内容则全部都变化
obj1.arr[0]="张三";
console.log(obj1.arr);
console.log(obj2.arr);
Borrow constructor
Core: Borrow the parent class constructor to enhance the subclass instance, that is, it is equivalent to copying a parent class property or method to the subclass.
Advantages: 1> Resolved the problem of subclass instances sharing parent class reference attributes. 2> When creating a subclass instance, you can pass parameters to the parent class constructor.
Disadvantages: Reuse is not possible. Each subclass instance has a new run function. If there are many objects in the instance, the memory consumption is too large.
//父亲函数
function Parent(name,arr){
this.userName=name;
this.arr=arr;
}
//子函数
function Child(name,arr){
this.age=18;
//借用构造函数的核心代码
Parent.call(this,name,arr);
}
var obj1 = new Child("张三", [1,2,3]);
var obj2 = new Child("张三", [1,2,3]);
//借用,不会产生关联
obj1.arr[0]="你好构造函数";
console.log(obj1.arr); //(3) ["你好构造函数", 2, 3]
console.log(obj2.arr); //[1, 2, 3]
Combinatorial inheritance (the most common way)
Advantages: 1> There is no problem of reference attribute sharing 2> Passable parameters 3> Method can be reused
Disadvantages: There is a redundant attribute of the parent class instance on the subclass prototype
//组合继承
//父亲函数
function Parent(name,arr){
//父类的私有属性 子类可以通过call() 使用
this.userName=name;
this.arr=arr;
}
//原型链可以复用函数 ,子类实例也可以使用
Parent.prototype.run=function(){
}
//子函数
function Child(name,arr){
this.age=18;
//借用父亲元素
Parent.call(this,name,arr); //借用构造函数(核心语句) 不能复用(具有私有的特点)
}
Child.prototype=new Parent(); //原型链(核心语句) arr是引用属性 一个改变 互相影响
var obj1 = new Child("张三", [1,2,3]);
var obj2 = new Child("张三", [1,2,3]);
//借用,不会产生关联
obj1.arr[0]="你好构造函数";
console.log(obj1.arr); //(3) ["你好构造函数", 2, 3]
console.log(obj2.arr); //[1, 2, 3]
Prototypal inheritance
Core: Use a function (child) to generate a new object (F)
Advantages: Regenerate a new object from an existing object, you do n’t need to create a custom type
Disadvantages; the reference attributes of the prototype will affect each other (shared an address) can not be achieved Code reuse, attributes are added later, no function encapsulation.
function fn(obj){ //用来生成新对象
function F(){} //构造函数
F.prototype=obj; //新的对象
return new F();
}
function Child(){ //构造函数
this.val=1;
this.age=18;
this.arr=[1,2,3];
}
var sub=new Child(); // 实例化child函数
var obj1=fn(sub);
var obj2=fn(sub);
obj1.arr[1]="张三";
console.log(obj1.arr); //[1, "张三", 3]
console.log(obj2.arr); //[1, "张三", 3]
Parasitic inheritance
Core: create new objects => enhanced objects (add attributes or methods), similar to the factory pattern
function fn(obj){
var F=function(){};
F.prototype=obj;
return new F();
}
//原型式
// function Sub(){
// this.name="张三";
// this.age=18;
// this.arr=[1,2,3];
// }
function getSub(obj){
//寄生核心
//新对象
var clone=fn(obj);
//增强
clone.attr1="class";
clone.att2="id";
return clone;
}
var obj1=new getSub({
name:"张三",
age:18,
arr:[1,2,3]
})
console.log(obj1.name); //张三
console.log(obj1.attr1); //class
function fn(obj){
var F=function(){};
F.prototype=obj;
return new F();
}
//原型式
// function Sub(){
// this.name="张三";
// this.age=18;
// this.arr=[1,2,3];
// }
function getSub(obj){
//寄生核心
//新对象
var clone=fn(obj);
//增强
clone.attr1="class";
clone.att2="id";
clone.brr=[1,2,3];
return clone;
}
var o={
name: "张三",
age: 18,
arr: [1, 2, 3]
}
var obj1=new getSub(o);
var obj2=new getSub(o);
//改变obj1的brr[0]的值,观察obj1和obj2对象中brr数组的变化
obj1.brr[0]=555;
console.log(obj1.brr); //[555, 2, 3]
console.log(obj2.brr); //[1, 2, 3]
Parasitic combined inheritance
Advantages: Fix the shortcomings of combined inheritance, only use the constructor once.
Disadvantages: Cumbersome writing
function fn(obj){
var F=function(){
}
//把obj实例挂着F的原型上
F.prototype=obj;
//返回新的对象F的实例
return new F();
}
//
function Sub(){
this.str="张三";
//基本属性
this.arr=[1,2,3];
//引用属性
}
//run是共享的
Sub.prototype.run=function(){
return "共享的run方法";
}
function SubType(){
Sub.call(this); //核心代码 借用sub构造函数
// Sub.call(this,参数1,参数2...)
}
//三步走
var obj1=fn(Sub.prototype); //核心 传递原型 改变this指向
obj1.constructor=SubType; //改变构造函数指向
Sub.prototype=obj1; //实例对象赋值给sub原型
//创建对象实例
var obj2=new SubType();
var obj3=new SubType();
obj2.arr[0]="张三";
console.log(obj2.arr); //["张三",2,3]
console.log(obj3.arr); // [1,2,3]