JS中的继承

前言

那么这篇文章是ES5的标准,所以有些内容可能会有一些,所以其它版本的标准可能会有一些不一样。

面向对象思想

面向对象编程思想:根据需求,分析对象,找到对象有什么特征和行为,通过代码方式来实现需求,要想实现这个需求,就要创建对象,要想创建对象,就应该显示有构造函数,然后通过构造函数来创建对象,通过对象调用属性和方法来实现相应的功能及需求

面向对象的三大特性:封装、继承、多态。那么这里主要说一说继承

继承的概念

继承可以使得子类具有父类的属性和方法或者重新定义、追加属性和方法等。

举一个简单的小例子:

改变原型指向继承

 // 例子:
    // 人:都有姓名、年龄、性别、吃饭、睡觉、玩
    // 学生:都有姓名、年龄、性别、吃饭、睡觉、玩,学习

    // js中通过继承来实现
    function Person(name, age, sex) {
        this.name = name;
        this.age = age;
        this.sex = sex;
    }

    Person.prototype.eat = function () {
        console.log("人可以吃东西");
    };
    Person.prototype.sleep = function () {
        console.log("人在睡觉");
    };
    Person.prototype.play = function () {
        console.log("生活就是不一样的玩法而已")
    };

    // 创建学生的构造函数
    function Student(score) {
        this.score = score;
    }

    // 该表学生的原型对象的指向即可 ===》 学生和人已经发生关系了
    Student.prototype = new Person("小红", 18, "女");
    Student.prototype.study = function () {
        console.log("学习就是一件时而枯燥无味,时而欣喜若狂的事情");
    };

    // 创建学生的实例对象
    var stu = new Student(98);

    // 冗余: 相同的代码太多,造成了代码的冗余(重复的代码)
    console.log(stu.name);
    console.log(stu.age);
    console.log(stu.sex);
    stu.play();
    stu.sleep();
    stu.eat();
    console.log("下面的是学生对象中自己有的");
    console.log(stu.score);
    stu.study();

运行结果如下
在这里插入图片描述
可以看到,在学生的构造函数中,我们并没有传入name,sex等等的参数,但是依然可以输出,这是因为我们修改了Stuent的原型指向,使它可以获得Person中的属性和方法,这就是继承。

借用构造函数继承

  • 为了让数据共享,改变原型的指向,做到了继承 – >通过原型指 向实现的继承.
    缺陷:因为改变原型指向的同时实现继承,直接初始化了属性,继承过来的属性的值都是一样的,所以, 这就是问题。只能重新调用对象的属性进行重新赋值。

  • 解决方法:继承的时候,不用改变原型的指向,直接调用父级的构造函数的方式来为属性赋值就可以了 — 借用构造函数:把要继

  • 借用构造函数:语法:构造函数的名字.call(当前对象, 属性, 属性, 属性);

举例:

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

    Person.prototype.sayHi = function () {
        console.log("您好");
    };

    function Student(name, sex, age, weight, score) {
        // 借用构造函数
        Person.call(this, name, sex, age, weight);
        this.score = score;
    }

    var stu1 = new Student("小明", "男", "14", "30kg","88");
    console.log(stu1.name, stu1.sex, stu1.age, stu1.weight, stu1.score);
    var stu2 = new Student("小置", "男", "16", "40kg", "67");
    console.log(stu2.name, stu2.sex, stu2.age, stu2.weight, stu2.score);
    var stu3 = new Student("小妮", "女", "17", "45kg", "95");
    console.log(stu3.name, stu3.sex, stu3.age, stu3.weight, stu3.score);

运行结果如下:
在这里插入图片描述
这种方法虽然解决了属性继承,并且值不重复的问题,但是在父类中的方法却不能够继承。

组合继承

组合继承就是将原型继承和借用构造函数继承融合在一起,那么这种继承方式既可以解决属性重复的问题,又可以继承到父类中的方法。
举例

 function Person(name, age, sex) {
        this.name = name;
        this.age = age;
        this.sex = sex;
    }
    Person.prototype.sayHi = function () {
        console.log("阿列哈撒哟");
    };
    function Student(name, age, sex, score) {
        // 借用构造函数,属性值重复的问题
        Person.call(this, name, age, sex);
        this.score = score;
    }

    // 改变原型的指向 -- 继承
    Student.prototype = new Person(); // 不传值
    Student.prototype.eat = function () {
        console.log("吃东西");
    };

    // 构建实例对象, 属性和方法都被继承了
    var stu = new Student("小黑", 20, "男", "100分");
    console.log(stu.age, stu.name, stu.sex, stu.score);
    stu.sayHi();
    stu.eat();

运行结果如下:
在这里插入图片描述

拷贝继承

拷贝继承就是把父类中的元素复制一遍,个人觉得不太常用
代码如下

function Person() {

    }
    Person.prototype.age = 10;
    Person.prototype.sex = "男";
    Person.prototype.height = 100;
    Person.prototype.play = function () {
        console.log("玩的好开心");
    };
    var obj2 = {};
    // Person的构造中有原型prototype,prototype就是一个对象,那么里面age,sex, height, play都是该对象的属性或方法

    for (var key in Person.prototype) {
        obj2[key] = Person.prototype[key];
    }
    console.dir(obj2);
    console.log(obj2.age);

小总结

  • 原型作用:数据共享,目的是:为了节省内存空间

  • 原型作用:继承 目的是:为了节省内存空间

  • 原型继承: 改变原型的指向

  • 借用构造函数继承:主要解决属性的问题

  • 组合继承: 原型继承+借用构造函数继承,既能解决属性问题,又能解决方法问题

  • 拷贝继承: 就是把对象中需要共享的属性或者方法,直接遍历的方式复制到另一个对象中

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值