JavaScript继承大全!

2021-01-07 11:26发布

前言:

JS里边的继承是工作中必用的,也是面试中必考的,所以这篇文章就给大家介绍一下每种继承的特点,希望对大家有所收获~!


 

原型链继承

    //父类        
    function Person(name) {
            this.name = name || 'hpp';
            this.sayName = function() {
                return this.name;
            }
    }
    //子类
    function Son() {
            this.age = 22;
    }
    Son.prototype = new Person();
    var p = new Son();
    console.log(p.name + p.age + p.sayName()) // hpp 22 hpp
    var p1 = new Per();
    //修改父类对象的属性
    p1.__proto__.name= 'wjf';
    console.log(p.name + p1.name); // wjf wjf
  • 关键点:让 Son构造函数的 prototype 属性 指向 一个 Person构造函数的实例!

  • 特点:


    • 继承实例构造函数的属性和方法

    • 继承父类构造函数的属性和方法

  • 缺点:


    • 实例无法向父类构造函数传参数

    • 单一继承,只能有一个父类

    • 所有实例对象都共享父类的属性和方法,会导致一个实例修改父类属性,其余实例的父类属性都被修改!


借用构造函数继承:

function Person(name) {
            this.name = name || 'hpp';
            this.sayName = function() {
                return this.name;
            }
        }
        function Man(){
            this.sex = '男';
            this.saySex = function(){
                return this.sex;
            }
        }
        function Per() {
            Person.apply(this,['wjf'])
            Man.call(this)
            this.age = 22;
        }
        var p = new Per();
        console.dir(p)
  • 关键点:使用 call 和 apply 方法将父类的构造函数引入子类里边

  • 特点:


    • 继承父类构造函数的属性和方法

    • 实例可以向父类构造函数传递参数

    • 可以继承多个父类

  • 缺点:


    • 只能继承父类构造函数的属性

    • 无法实现构造函数的复用

    • 每个实例都有父类构造函数的副本


 

组合继承(原型链继承 + 构造函数继承)

function Person(name) {
            this.name = name || 'hpp';
            this.sex = sex || 'man'
        }
        Person.prototype.sayInfo = function() {
            return this.name + this.sex;
        }
        function Per() {
            Person.apply(this, ['wjf', 'man'])
            this.age = 22;
        }
        Per.prototype = new Person();
        Per.prototype.constructor = Per;
        var p = new Per();
        p.sayInfo()
        console.dir(p)
  • 关键点;


    • 子类继承父类的属性

    • 父类的公共方法放到 prototype 上边,实现多个 实例共享

  • 缺点:


    • 调用了两次父类

  • 优点:


    • 每个实例都有自己的属性,同时可以共享公共的方法


原型式继承:

 function Person(name) {
            this.name = name || 'hpp';
            this.colors = [];
    }
    function Per(obj) {
            function F(){};
            F.prototype = obj;
            return new F();
    }
    var p = new Person();
    var pp = Per(p);
  • 关键点:


    • 用一个函数包装一个对象,然后返回这个函数的调用,object.create()就是这个原理,浅复制对象

  • 特点:


    • 包装对象

  • 缺点:


    • 原型的引用类型属性会在各实例之间共享


寄生式继承

function Person(name) {
            this.name = name || 'hpp';
            this.colors = [];
        }
        function Object(obj) {
            function F(){};
            F.prototype = obj;
            return new F();
        }
        function CreateAnother(original){
            var clone = Object(original);
            clone.sayHi = function(){
                console.log('hi');
            }
            return clone;
        }
        var p = new Person();
        var pp = CreateAnother(p);
        pp.sayHi();
  • 关键点:


    • 创建一个用于封装继承过程的函数,这个函数可以在内部以某种方式增强对象,然后返回包装好的对象

  • 缺点:


    • 使用寄生方式为对象添加函数,无法做到复用


寄生组合式继承

function Person(name) {
            this.name = name || 'hpp';
            this.colors = [];
        }
        function Object(obj) {
            function F(){};
            F.prototype = obj;
            return new F();
        }
        function CreateAnother(son,father){//寄生的关键,封装一个函数过程,用于增强对象
            var clone = Object(father);
            clone.constructor = son;
            son.prototype = clone;
        }
        function Boy(name,age){
            Person.call(this,name)//借用构造函数
            this.age=age;
        }
        Boy.prototype.sayMyInfo = function(){
            console.log(this.name,this.age);
        }
        var p = new Person();
        var pp = new Boy('wjf',22);
        CreateAnother(pp,p);
        pp.sayMyInfo();
  • 特点:


    • 只调用了一次父类构造函数,避免了在子类的prototype上边创建爱你不必要的属性。

    • 保持了原型链不变

    • 正常使用 instanceof 和 isProtytypeOf() 方法



作者:靖凡无所畏惧

链接:https://blog.csdn.net/wjf1997/article/details/108555441

来源:CSDN
著作权归作者所有,转载请联系作者获得授权,切勿私自转载。