JS中的继承

1 什么是继承

        继承是一种类(class)与类之间的关系,JS中没有类,但是可以通过构造函数模拟类,然后通过原型来实现继承,

  • 继承是为了实现数据共享,js中的继承当然也是为了实现数据共享。
  • 继承是子类继承父类的特征或者行为,使子类也具有父类的属性和方法;
  • 或者子类从父类继承方法,使得子类具有父类相同的行为
  • 继承可以使得子类具有父类的各种属性和方法,而不需要再次编写相同的代码。

2 通过原型实现继承 

 2.1案例一

function Person1(name,age,sex){
        this.name = name;
        this.age = age;
        this.sex = sex;
    }
Person1.prototype.eat = function(){
        console.log("第一次吃好吃的!!!");
            }
    Person1.prototype.sleep = function(){
        console.log("第一次睡觉!!!");
    }
    Person1.prototype.study = function(){
        console.log("第一次学习做人!!!");
    }

    //学生
    function Student1(score){
        this.score = score;
    }

    //改变学生的原型的指向即可让学生继承Person1
    Student1.prototype = new Person1("张三",18,"男");
    Student1.prototype.study = function(){
        console.log("学习真的好难!!!");
    }


    var stu1 = new Student1(99);
    console.log("学生从人中继承的属性和行为!!!");//学生从人中继承的属性和行为!!!
    console.log(stu1.name,stu1.age,stu1.sex);//张三 18 男
    stu1.eat();//第一次吃好吃的!!!
    stu1.sleep();//第一次睡觉!!!
    console.log("学生中有自己的属性和行为!!!");//学生中有自己的属性和行为!!!
    console.log(stu1.score); //99
    stu1.study();// 学习真的好难!!!  这里输出"学习真的好难" 而不是 "第一次学习做人"  
                 // 因为实例对象访问某个属性的时候,应该先从实例对象中找,找到了就直接用,没有找到就去指向的原型对象中找,找到了就使用,没有找到就返回undefined 

 2.2案例二

//继承实例
    function Animal(name,weight){
        this.name = name;
        this.weight = weight;
    }

    //动物的原型方法
    Animal.prototype.eat = function(){
        console.log("兄弟们冲啊,赶快吃吃吃!!!");
    }

    //狗的构造函数
    function Dog(color){
        this.color = color;
    }

    Dog.prototype = new Animal("小三","30kg");
    Dog.prototype.bitePerson = function(){
        console.log("~汪汪汪,快让开,我要咬人了!!!");
    }

    //哈士奇构造函数
    function Husky(age){
        this.age = age;
    }
    Husky.prototype = new Dog("黑白色");
    Husky.prototype.playYou = function(){
        console.log("咬坏充电器,咬坏耳机,拆家...哈哈,好玩不!!!");
    }

    var husky = new Husky(3);
    console.log(husky.name,husky.weight,husky.color,husky.age);//小三 30kg 黑白色 3
    husky.eat();//兄弟们冲啊,赶快吃吃吃!!!
    husky.bitePerson();//~汪汪汪,快让开,我要咬人了!!!
    husky.playYou();//咬坏充电器,咬坏耳机,拆家...哈哈,好玩不!!!

2.3 借用构造函数实现继承

  • 在上边的讲解中,我们为了数据共享,改变了原型指向,做到了继承,即通过改变原型指向实现了继承。
  • 这导致了一个问题,因为我们改变原型指向的同时,直接初始化了属性,这样继承过来的属性的值都是一样的了。
  • 这是个问题,如果我们想要改变继承过来的值,只能重新调用对象的属性进行重新赋值,这又导致我们上边的初始化失去了意义。
    function Person2(name,age,sex,weight){
        this.name = name;
        this.age = age;
        this.sex = sex;
        this.weight = weight;
    }
    Person2.prototype.sayHi = function(){
        console.log("第二次说你好帅啊!!!");
    };

    function Student2(score){
        this.score = score;
    }

    Student2.prototype = new Person2("张三",18,"男","50kg");

    var stu2 = new Student2(60);
    console.log(stu2.name,stu2.age,stu2.sex,stu2.weight);//张三 18 男 50kg
    stu2.sayHi();//第二次说你好帅啊!!!


    function Person3(name,age,sex,weight){
        this.name = name;
        this.age = age;
        this.sex = sex;
        this.weight = weight;
    }

    function Student3(name,age,sex,weight,score){
        Person3.call(this,name,age,sex,weight);//改变this指向
        this.score = score;
    }

    var stu3 = new Student3("李四",16,"男","70kg",66);
    console.log(stu3.name,stu3.age,stu3.sex,stu3.weight,stu3.score);//李四 16 男 70kg 66

    var stu4 = new Student3("王五",20,"女","60kg",82);
    console.log(stu4.name,stu4.age,stu4.sex,stu4.weight,stu4.score);//王五 20 女 60kg 82

2.4 组合继承

  • 原型继承和借用构造函数继承都存在各自的缺点,我们可以将这二者结合到一起,从而发挥二者之长。
  • 即在继承过程中,既可以保证每个实例都有它自己的属性,又能做到对一些属性和方法的复用。这时组合继承应运而生,组合继承=原型继承+借用构造函数继承。
function Person4(name,age,sex){
        this.name = name;
        this.age = age;
        this.sex = sex;
    }

    Person4.prototype.sayHi = function(){
        console.log("第四次说你好帅呀!!!");
    }

    function Student4(name,age,sex,score){
        //借用构造函数,解决属性值重复的问题
        Person4.call(this,name,age,sex);
        this.score = score;
    }

    //改变原型指向,原型继承解决原型方法不能被继承问题
    Student4.prototype = new Person4();//不传值
    Student4.prototype.eat = function(){
        console.log("第四次吃吃吃了!!!");
    }
    
    var stu44 = new Student4("王五",18,"男",96);
    console.log(stu44.name,stu44.age,stu44.sex,stu44.score);//王五 18 男 96
    stu44.sayHi();//第四次说你好帅呀!!!
    stu44.eat();//第四次吃吃吃了!!!

    var stu55 = new Student4("赵六",15,"女",93);
    console.log(stu55.name,stu55.age,stu55.sex,stu55.score);//赵六 15 女 93
    stu44.sayHi();//第四次说你好帅呀!!!
    stu44.eat();//第四次吃吃吃了!!!

2.5 另一种继承方式:拷贝继承(for-in)

  • 拷贝继承:把一个对象中的属性或者方法直接复制到另一个对象中。
function Person5(){}
    Person5.prototype.name = "小三";
    Person5.prototype.age = 18;
    Person5.prototype.sex = "男";
    Person5.prototype.height = 100;
    Person5.prototype.play = function(){
        console.log("我玩的好开心啊!!!");
    };
    
    var obj = {};

     // Person中有原型prototype,prototype就是一个对象,那么里面,name,age,sex,height,play都是该对象中的属性或者方法
    // 新对象obj通过拷贝Person中原型prototype对象中的属性和方法继承Person中原型prototype对象的属性和方法

    for(var key in Person5.prototype){
        obj[key] = Person5.prototype[key];
    }
    console.log(obj);//{name: "小三", age: 18, sex: "男", height: 100, play: ƒ}
    obj.play();//我玩的好开心啊!!!

3 总结

原型链是一种关系,是实例对象和原型对象之间的关系,这种关系是通过原型(proto)来联系的。继承是类与类之间的关系,js不是面向对象的语言,没有类但可以通过函数模拟类,模拟面向对象中的继承。模拟继承是为了实现数据共享,节省内存空间。


JS中的继承方式:

  1. 原型继承:通过改变原型的指向实现继承。
  2. 借用构造函数继承:主要解决属性重复的问题,会导致父类中的原型方法不能继承。
  3. 组合继承:原型继承+借用构造函数继承,既能解决属性重复问题,又能解决方法不能被继承的问题。
  4. 拷贝继承:把对象中需要共享的属性或方法,直接通过遍历的方式复制到另一个对象中。
  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值