JavaScript 类继承与原型继承的区别

点击上方 "程序员小乐"关注, 星标或置顶一起成长

每天凌晨00点00分, 第一时间与你相约

每日英文

Sometimes,God does not give you what you want,it is not because you do not deserve it but for the better. 

有时候,上天没有给你想要的,不是因为你不配,而是你值得更好的。

每日掏心

有人说人生无奈,但人定胜天,我们可以改变。的确,也许唯有充实人生,才能弥补一些遗憾不足,让自己快乐多一点烦恼少一点。

来自:牛鼻子老邵 | 责编:乐乐

链接:jianshu.com/p/e446e1f08b12

JavaScript 类继承与原型继承的区别_第1张图片

程序员小乐(ID:study_tech)第 739 次推文   图片来自 Pexels

往日回顾:Java泛型背后是什么?

   正文   

在 ES6 之前,JavaScript 实现两个对象的继承一般有两种方法。

一种方法是利用 this 与构造函数。

function Parent(name,height) {
    this.name = name;
    this.height = height;
}

function Child(age) {
    Parent.apply(this,['hahaha',171])
    this.age = age;
}

let ch = new Child(21);

console.log(ch.name)

在这种方法中,利用 apply 或 call,在一个函数中改变了另一个函数的 this 指向并运行。结果是一个构造函数的实例,继承了另一个构造函数的属性和方法。这种方法有一个缺点,对于原型链上的继承没有实现。

另一种方法是利用原型链实现属性的继承。

function Parent(name,height) {
    this.name = name;
    this.height = height;
}

function Child(age) {
    this.age = age;
}

Child.prototype = new Parent('hahaha',171);

let ch = new Child(21)

console.log(ch.name)

这种方法与其说是继承,不如说是一种查找规则。JavaScript 中如果在一个对象中找不到相关属性和方法,就会沿着原型链向上查找。在这段代码中,将 Child 的原型对象设置为 Parent 的一个实例,也就是将 Child 实例原型链的上一层设置为 Parent 的一个实例。由此实现了一个对象继承了另一个对象的效果。

这种方法也有个缺点,继承了同一个原型的两个实例之间相互影响。

在 ES6 之后,有了类的书写方法。

class Fruit {
    constructor (name,quantity){
        this.name = name;
        this.quantity = quantity;
    }
    static show() {
        return 'show'
    }
    getName() {
        return this.name;
    }
}

class Apple extends Fruit {
    constructor (name,quantity,area) {
        super(name,quantity);
        this.area = area;
    }
}

let apple = new Apple('apple',3,'shan');
console.log(Apple.show() +':'+ apple.getName()+'  ' + apple.quantity)
// show:apple  3

类的继承语法更直观,书写更简便,它与 ES5 的继承有几点不同。

  1. getPrototypeOf 结果不同
    类继承中子类会 [[Prototype]] 链接到父类,原型继承中的构造函数都是通过 prototype 指向的原型对象相互联系的。一般在原型继承中,子构造函数的原型对象是父构造函数,或者子构造函数的原型对象 [[Prototype]] 链接到父构造函数的原型对象。

  2. this 创造顺序不同
    ES5 的继承,实质是先创造子类的实例对象this,然后再将父类的方法添加到this上面(Parent.apply(this))。ES6 的继承先将父类实例对象的属性,加到this上面(所以必须先调用super方法),然后再在子类中修改this。

  3. 子类实例的构建,基于父类实例,只有super方法才能调用父类实例。

参考文章阮一峰: Class 的继承

es6.ruanyifeng.com/#docs/class-extends

欢迎在留言区留下你的观点,一起讨论提高。如果今天的文章让你有新的启发,学习能力的提升上有新的认识,欢迎转发分享给更多人。

欢迎各位读者加入程序员小乐技术群,在公众号后台回复“加群”或者“学习”即可。

猜你还想看

阿里、腾讯、百度、华为、京东最新面试题汇集

Redis Sentinel 架构原理详解

Java 会走向晦暗吗?Kotlin 会取而代之吗

一次SQL优化的体验

关注「程序员小乐」,收看更多精彩内容

嘿,你在看吗

你可能感兴趣的:(JavaScript 类继承与原型继承的区别)