Simple understanding of JavaScript object inheritance

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]
49 original articles published · Like 3 · Visits 5108

Guess you like

Origin blog.csdn.net/weixin_43487066/article/details/104349671