js内建对象的继承

我看书上说ES6之前的js无法真正实现内建对象的继承,但原因不是很明白,例如内建数组Array对象的继承:

function MyArray() {
    Array.apply(this, arguments)
}
MyArray.prototype = Object.create(Array.prototype, {
    constructor: {
        value: MyArray,
        writable: true,
        configurable: true,
        enumerable: true
    }
})
const arr = new MyArray()
      arr1 = new Array();
arr[0] = 'a'; arr1[0] = 'a'
console.log(arr[0], arr1[0]); // a a
arr.length = 0;  arr1.length = 0;
console.log(arr[0], arr1[0]); // a undefined  和原生的产生了差异,没有实现真正的继承

但为什么会出现这样的差异呢,书上的解释:

在ECMAScript 5的传统继承方式中,先由派生类型(例如,MyArray)创建this的值,然后调用基类型的构造函数(例如Array.apply()方法)。这也意味着,this的值开始指向的是MyArray的实例,但是随后会被来自Array的其他属性所修饰。ECMAScript 6中的类继承则与之相反,先由基类(Array)创建this的值,然后派生类的构造函数(MyArray)再修改这个值。所以一开始可以通过this访问基类的所有内建功能,然后再正确地接收所有与之相关的功能。

不是很明白,在我的理解,继承就是将父类实例中的属性(也就是this.属性名)拷贝到子类实例中,然后让子类的原型指向父类的原型,继承原型的方法,这样子类就可以使用所有子类可以使用的,这样说的话上面的写法已经实现了继承,能解释一下为什么没有实现真正的继承吗?

阅读 1.4k
1 个回答
const arr = new MyArray()
// 若不想使用 ES6 类继承,可以通过下面 API 实现,但 ES5 不支持
const arr = Reflect.construct(Array, [], MyArray)

具体原因是因为你在用 ES5 模拟 ES6 继承的时候,实例对象是先通过子类构造函数产生,也就是先 new 进行子类实例化,然后再通过父类构造函数构造。
而真正的 ES6 类继承,实例对象是通过父类构造函数产生,也就是说 new 要先调用 super() 进行父类实例化,然后再通过子类构造函数构造。
两者的区别在于实例对象的真正起源不同、构造过程的时序和具体实例的行为表现不同。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题