JS中的几种继承方式(JavaScrip继承)

作为初学者,结合了自己最近所学,记录下继承的几种方式,如果有错,请指导,如有侵权,请告知,谢谢!

继承继承,就有父类

        function Father(name, age) {

            this.name = name; this.age = age;  //实力属性

            this.sayHi = () => { console.log(this.name + '今年' + this.age + '岁了') }    //实力方法

        };

//原型方法

  Father.prototype.sayMe = `我是$2104班级`;

  Father.prototype.eat = (food) => { console.log("我爱吃" + food) };

 // 后台检测

        // let fat = new Father('Joy', 14);

        // console.log(fat, fat.sayMe)

        // fat.sayHi();

        // fat.eat('玉米')

        // console.log(fat instanceof Father);   //true

继承方法1(原型链继承)

(将父类的实例作为子类的原型)

         function Child() { };

        Child.prototype = new Father();

        Child.prototype.name = "Tom";

        Child.prototype.age = 18;       

        let child = new Child("Boy",18);    //Boy,18无法实现传参

        console.log(child, child.sayMe);

        child.sayHi();

        child.eat();     //我爱吃undefined

        child.eat('桃子');

        console.log(child instanceof Father);  //true

        console.log(child instanceof Child);    //true

// 特点:非常单纯的继承关系,实例是子类的实例,也是父类的实例;父亲新增的属性,子类都能访问;简单

        // 缺点:为子类添加属性或方法,要在new语句后执行,不能放在构造器中;无法实现多继承;创建子类实例,无法向父类传参

继承方法2(构造函数继承)复制父类的实例属性给子类,没有原型)

 function Child(name, age) {

            Father.apply(this, arguments);

            // this.name = name || "Lucy";

            // this.age = age || 15;

        };

         let child = new Child('Jack', 14);  //可以传参,如果没传参用内置的参数

        // let child = new Child();

        console.log(child);

        console.log(child.sayMe); //undefined

        child.sayHi();

        // child.eat();     //报错

        child.eat('西瓜');

        console.log(child instanceof Father);  //false

        console.log(child instanceof Child);    //true

// 特点:解决子类实例共享父类引用属性的问题;创建子类时;可以向父类传递参数;可以实现多继承

        // 缺点:实例是父类的不是子类的实例;只能继承实例的属性、方法不能继承原型的;每个子类都有父类的实例的函数副本,影响性能

 继承方法3(实例继承)为父类添加新特性,作为子类实例返回)

 function Child(name, age) {

            let F = new Father();

            F.name = name || "Lucy";

            F.age = age || 15;

            return F;

        };

        let child = new Child('Bob', 19);

        console.log(child);

        console.log(child.sayMe);

        child.sayHi();

        child.eat('西瓜');

        console.log(child instanceof Father);  //true

        console.log(child instanceof Child);    //false

// 特点:不限制调用方法,不管是new Child() 还是 子类(),返回的对象具有相同的效果

 // 缺点:实例是父类的实例,不是子类的实例

 // 继承方法4(拷贝继承)

        function Child() {

            Father.apply(this, arguments);

            let F = new Father();

            for (let a in F) {

                Child.prototype[a] = F[a];

            };

        };

        let child = new Child('Xicy', 20);

        console.log(child);

        console.log(child.sayMe);

        child.sayHi();

        child.eat('西瓜');

        console.log(child instanceof Father);  //false 

        console.log(child instanceof Child);    //true

        // 特点:支持多继承

        // 缺点:效率较低,占用内存多,无法获取父类不可枚举的属性或方法(有的不可枚举方法,无法用forin访问到)

// 继承方法5(组合继承)(通过调用父类构造,继承父类的属性并保留传参的优势,然后通过父类的实例作为子类的原型,实现服用)

        function Child(name,age) {

            Father.apply(this, arguments);

           // this.name = name || "Lucy";

            //this.age = age || 15;

        }; 

        Child.prototype = new Father();

        Child.prototype.constructor = Child;

        let child = new Child('Reg', 175);

        // let child = new Child();

        console.log(child);

        console.log(child.sayMe);

        child.sayHi();

        child.eat('西瓜');

        console.log(child instanceof Father);  //true

        console.log(child instanceof Child);    //true

        // 特点:弥补了构造继承的求点,不存在属性共存的问题,可传参,可复用

        // 缺点:调用了2次父类的构造,生成了2份实例

// 继承方法6(原型式继承)

        function inherite(father) {

            const F = function () { };

            F.prototype = father;

            F.prototype.constructor = F;

            return new F();

        };

        let father = new Father('Taken', 20);

        let child = inherite(father);

        console.log(child);

        console.log(child.sayMe);

        child.sayHi();

        child.eat('西瓜');

        console.log(child instanceof Father);  //true

        console.log(child instanceof inherite);    //false  

//用一个函数包装一个对象,然后返回这个函数的调用。 Object.create()就是这个原理

继承方法7(寄生继承)(通过寄生方式,砍掉了父类的实例属性,这样,在调用2次父类的构造,就不会初始化2次实例的属性、方法)

function inherite(child, father) {

            const F = function () { };

            F.prototype = father.prototype;

            child.prototype = new F();

            child.prototype.constructor = child;

        };

        function Child(name, age) {

            Father.apply(this, arguments);

            this.name = name || "Lucy";

            this.age = age || 15;

        };

        inherite(Child, Father)

        // let child = new Child('Date', 75);

        let child = new Child();

        console.log(child);

        console.log(child.sayMe);

        child.sayHi();

        child.eat('苦瓜');

        console.log(child instanceof Father);  //true

        console.log(child instanceof Child);    //true

        // 特点:缺点几乎没有

        // 缺点:过程比较复杂

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值