欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

js学习中的总结——几种继承模式

程序员文章站 2022-06-15 12:19:42
...

        js中构造函数的几种继承模式浅析

一、原型链模式继承

    利用原型让一个引用类型继承另一个引用类型的属性和方法 。

    用的最多。

    缺点:不可传参,不可多继承。

function People(name, age) {//添加公有属性
            name = name || 'xiaolan';
            age = age || 18;
            this.name = name;
            this.age = age;
        }//创建一个名为People的类
        People.prototype.eat = function() {//添加私有属性
            console.log(this.name + '贼能吃');
        }
        function Cat(color) {//创建一个名为Cat的类
            this.color = color;
        }
        Cat.prototype = new People('小叮当', 200);//实例化一个People类,并赋值给Cat类的原型链
        var cat = new Cat('蓝白色')
        console.log(cat.name)//'小叮当'
        cat.eat();//'小叮当贼能吃'

二、混合模式继承

    用call的方法只能继承私有属性,所以再加一遍一遍原型链模式继承,原型链模式继承又把私有属性和公有属性都继承了一遍。

  function People(name, age) { //创建一个父级People类
            name = name || 'xiaolan';
            age = age || 18;
            this.name = name;
            this.age = age;
        }
        People.prototype.eat = function() {
            console.log(this.name + '贼能吃');
        }

        function Cat(color, name, age) {
            this.color = color;
            People.call(this, name, age); //通过call的形式继承
            //通过call(this),将People的指向改为Cat的实例
        }
        var cat = new Cat('蓝白色', '小叮当', 1);
        console.log(cat.name);//'小叮当'
        cat.eat();//报错,
        //继承不了公有属性,所以cat.eat()会报错;

为了继承公有属性,用原型链模式在把公有属性和方法继承过来,

 function People(name, age) { //创建一个父级People类
            name = name || 'xiaolan';
            age = age || 18;
            this.name = name;
            this.age = age;
        }
        People.prototype.eat = function() {
            console.log(this.name + '贼能吃');
        }

        function Cat(color, name, age) {
            this.color = color;
            People.call(this, name, age); //通过call的形式继承
            //通过call(this),将People的指向改为Cat的实例
        }
        Cat.prototype = new People()
        var cat = new Cat('蓝白色', '小叮当', 200)
        console.log(cat)
        console.log(cat.name); //'小叮当',在原型链继承的时候,就近原则,cat.name 先找到'小叮当',就不往下找了
        cat.eat(); //'小叮当贼能吃'

三、拷贝继承

    优点:可以多继承,可传参;

    缺点:浪费资源,不能判断父级;

        function People(name, age) { //创建一个父级People类
            name = name || 'xiaolan';
            age = age || 18;
            this.name = name;
            this.age = age;
        }
        People.prototype.eat = function() {
            console.log(this.name + '贼能吃');
        }

        function Cat(color, name, age) {
            this.color = color;
            var people = new People(name, age) //实例化一个People类
            for (let i in people) {
                this[i] = people[i]; //将people中的可枚举属性和方法遍历并附给Cat类,公有属性和私有属性都是可枚举属性;
            }
        }
        var cat = new Cat('蓝白色', '小叮当', 2);
        console.log(cat.name); //小叮当
        cat.eat(); //小叮当贼能吃

四、寄生组合方式继承

    优点:私有属性和公有属性都单独继承,可以传参;

    私有属性可以多继承,公有属性不可多继承;

        function People(name, age) {
            name = name || 'xiaolan';
            age = age || 18;
            this.name = name;
            this.age = age;
        }
        People.prototype.eat = function() {
            console.log(this.name + '贼能吃');
        }

        function Cat(color, name, age) {
            this.color = color;
            People.call(this, name, age) //用call的形式把私有属性继承过来
        }

        function Fn() {} //创建一个中间构造函数,用来接收People的公有属性,为了防止创建实例Cat实例是影响原来的people构造函数
        Fn.prototype = People.prototype;
        Cat.prototype = new Fn(); //将中间构造函数Fn继承people的公有属性传给Cat的原型链
        Cat.prototype.constructor = Cat; //由于上一步重置了Cat原型链的constructor属性,所以要重新给赋回来;
        var cat = new Cat('蓝白色', '小叮当', 3);
        console.log(cat.name); //'小叮当'
        cat.eat() //'小叮当贼能吃


注:若有不严谨与错误的地方,请多指教!


相关标签: js 继承