【问题标题】:Inheriting from Array从数组继承
【发布时间】:2016-10-26 02:35:12
【问题描述】:

我试图在不使用 ES6 class 语法糖的情况下继承 Array 的所有方法。此外,我希望像 new MyArray().map() 这样的方法返回 MyArray 的实例。

我的问题的简单说明:

class MyArrayES6 extends Array{}

new MyArrayES6().slice() instanceof MyArrayES6 //true

function MyArray(){}
MyArray.prototype = Object.create(Array.prototype)
MyArray.prototype.constructor = MyArray
MyArray[Symbol.species] = MyArray //Doing this doesn't affect the outcome

new MyArray().slice() instanceof MyArray //false, to my suprise!

A more complete code example 编辑:给出更清晰的例子

【问题讨论】:

  • 最后是寂寞So, ..?
  • 可悲的是,它死于孤独:(

标签: ecmascript-6 symbols


【解决方案1】:

问题是ArraySpeciesCreate在对象不是数组时不使用@@species。

如果你不使用extends Array,默认情况下实例不会是数组。

如果你真的想让它工作,你仍然可以返回一个带有修改过的 [[Prototype]] 的真实数组:

function ArraySub(){
  return Object.setPrototypeOf([], ArraySub.prototype);
}
ArraySub.prototype = Object.create(Array.prototype)
ArraySub.prototype.constructor = ArraySub
ArraySub[Symbol.species] = ArraySub;
console.log( new ArraySub().slice() instanceof ArraySub );

但这会严重影响性能。最好使用extends Array

【讨论】:

  • 很好的答案。这是否意味着 ES6 class 提供的不仅仅是语法糖?似乎没有好的方法可以在不覆盖 Array 原型的情况下复制该行为,这不仅仅会损害性能。编辑:废弃它,它只会损害性能
  • 最好使用new.target.prototype 而不是ArraySub.prototype 进行正确的子类化。别忘了Object.setPrototypeOf(ArraySub, Array)
  • @Batmoose 是的。只有使用 class 语法才能正确继承内置函数。
  • setPrototypeOf 的替代品是Reflect.construct,但这与class 存在相同的可用性问题..
  • 太好了,谢谢!这在规格中很难追踪。正如@loganfsmyth 暗示的那样,使用Reflect.construct 也可以完成这项工作:function ArraySub(...args) { return Reflect.construct(Array, args, ArraySub); } Object.setPrototypeOf(ArraySub.prototype, Array.prototype); Object.setPrototypeOf(ArraySub, Array); console.log(new ArraySub().slice() instanceof ArraySub); // true
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-07
  • 2020-03-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多