ES6与ES5继承的解析

如果对JS继承还不甚了解,可以阅读一下《前端学习系列——(十)JavaScript的继承》

我们先构造好父类:

function Super() {
    
    
	this.name = '随风丶逆风'
}

寄生组合继承

ES5继承方式中,普遍认为寄生组合继承最优,这里就以它为例:

function Sub1() {
    
    
	Super.call(this)
}
// 用于解决组合继承导致父类属性被两次实例化的问题。即子类一份属性,子类原型上又有一份
Sub1.prototype = Object.create(Super.prototype)
// 修正Sub原型对象上[[Constructor]]指针,从Super指向Sub,方便使用contructor判断构造函数
Sub1.prototype.constructor = Sub1

ES6继承

ES6新增了class语法糖,使用extends关键词进行继承。

值得注意的是,extends关键字可以继承任意具有[[Construct]]和prototype的对象,这是为了向后兼容,继承普通的构造函数。

class Sub2 extends Super {
    
    }

两者的相同点

  1. 子类继承了父类的实例属性和方法
const sub1 = new Sub1()
const sub2 = new Sub2()

sub1.hasOwnProperty('name') // true
sub2.hasOwnProperty('name') // true 

在这里插入图片描述

  1. 子类继承了父类的原型属性和方法,即子类的原型对象的[[Prototype]]指针指向父类的原型对象(原型链)
Sub1.prototype.__proto__ === Super.prototype // true
Sub2.prototype.__proto__ === Super.prototype //true

在这里插入图片描述

两者的不同点

都知道class是语法糖,虽然本质上还是原型继承那一套,但是从语法规范以及实现上而言,还是有些微差别。

ES6静态属性和方法的继承

ES6存在两条“继承链”:

  • 其一,实例和原型的属性及方法的继承与ES5基本一致;
  • 其二,构造函数继承,在JS中万物皆是对象,构造函数本身也是个对象,它的[[Prototype]]指针原本是指向Function.prototype,ES6为继承父类的静态属性和方法,将子类的[[Prototype]]指针直接指向了父类,这样就通过原型链访问到了父类的静态属性和方法。
Super.static = 'static'

Sub1.static // undefined
Sub2.static // 'static'
Sub1.__proto__ === Super // false
Sub2.__proto__ === Super // true
Sub1.hasOwnProperty('static') // false
Sub2.hasOwnProperty('static') // false

在这里插入图片描述

super关键字

  • ES5是先构造子类的this,然后将父类的实例属性通过call或者bind绑定到子类this上;
  • ES6子类是先构造父类this,然后在this上添加属性和方法,所以子类必须在constructor()中显式调用super()才能使用this,因为子类并不存在this

猜你喜欢

转载自blog.csdn.net/sinat_36521655/article/details/109830475
今日推荐