js实现继承的七种方法

     //1.构造函数(利用call等改变this指向)-----------同比创建对象的构造函数模式
        function Parent1() {
            this.name = '父'
        }

        function Son1() {
            Parent1.call(this); //将子类的this使用父类的构造函数跑一遍
        }
        var s1 = new Son1();
        console.log(s1 instanceof Parent1); // false
        console.log(s1 instanceof Son1); //true
        //特点:可以实现多继承(call);可以向父类传参;子类实例共享父类成员(非原型上的)
        //缺点:Person1原型链上的成员不会被子类继承

        //2.原型链继承(将父类的实例作为子类的原型)-----------同比创建对象的原型链模式
        function Parent2() {
            this.name = '原型链';
        }

        function Son2() {
            this.type = 'child';
        }
        Son2.prototype = new Parent2();
        var s2 = new Son2();
        console.log(s2 instanceof Parent2); // true
        console.log(s2 instanceof Son2); // true //
        //特点:实例时子类的实例也是父类的;父类新增的原型方法/属性,子类都能访问
        //缺点:无法实现多继承;来自原型对象的所有属性被所有实例共享;创建子类实例时,无法向父类传参

        //3.实例继承(为父类添加新特性,作为子类实例返回)-----------同比创建对象的工厂模式
        function Parent3() {}

        function Son3(name) {
            var s = new Parent3();
            s.name = '实例继承'
            return s;
        }
        var s3 = new Son3();
        var s31 = Son3();
        console.log(s3 instanceof Parent3); // true
        console.log(s3 instanceof Son3); //false
        console.log(s31 instanceof Parent3); // true
        console.log(s31 instanceof Son3); //false
        //特点:不限制调用方式,不管是new 子类()还是子类(),返回的对象具有相同的效果
        //缺点:实例是父类的实例,不支持多继承

        //4.拷贝继承
        function Parent4() {}

        function Son4() {
            var p = new Parent4();
            for (var k in p) {
                Son4.prototype[k] = p[k];
            }
        }
        var s4 = new Son4();
        console.log(s4 instanceof Parent4); // false
        console.log(s4 instanceof Son4); //true
        //特点:支持多继承
        //缺点:效率低,占内存(拷贝父属性)

        //5组合继承(调用父类构造,继承父成员,然后将父实例作为子原型,实现函数复用)
        function Parent5(name) {}

        function Son5(name) {
            Parent5.call(this);
        }
        Son5.prototype = new Parent5();
        var s5 = new Son5();
        console.log(s5 instanceof Parent5); // true
        console.log(s5 instanceof Son5); //true
        //特点:可以继承实例属性方法,也可以继承原型属性方法;即是子类实例也是父类;可以传参
        //缺点:调用了俩次父类构造函数,生成了俩实例,多占内存

        //6.寄生组合继承()
        function Parent6() {}

        function Son6() {
            Parent6.call(this);
        }
        Son6.prototype = Object.create(Parent6.prototype); 
        //记得new过程吗,前两步(创建空对象,将构造函数的原型对象赋值给空对象 对象原型)
        //修复this指向
        Son6.prototype.constrctor = Son6
        var s6 = new Son6();
        console.log(s6 instanceof Parent6); // true
        console.log(s6 instanceof Son6); //true
        //实现复杂

        //7.ES6
        class People {
            constructor(name) {
                this.name = name;

            }
            eat() {
                console.log(`${this.name} eat food`)
            }
        }
        //继承父类
        class Woman extends People {
            constructor(name) {
                //继承父类属性
                super(name);
            }
            eat() {
                //继承父类方法
                super.eat();
            }
        }
        let wonmanObj = new Woman('wang');
        wonmanObj.eat();
        //es6,class中只能定义方法,不能定义对象变量等,没有prototype,必须用new调用

用原生封装继承

 //原生继承(就是将寄生组合修改了一下)
        function extendsClass(Parent, Son) {
            function O() {}
            O.prototype = parent.prototype;
            Son.prototype = new O();
            Son.prototype.constrctor = Son;
            return Son;
        }

你可能感兴趣的:(JavaScript)