javascript - 扩展内置数组,super() 的行为很奇怪

标签 javascript ecmascript-6 es6-class

我正在尝试扩展 JS 的原生 Array这样我就有一个实现随机洗牌的数组,如下所示:

 class RandomArray extends Array {

  // Fisher Yates shuffle. Shuffles from the back. 
  // Performs n = size number of shuffles. 
  shuffle(size) {
    size = size || this.length

    if (size > this.length) {
      throw RangeError("Number of shuffles must be fewer than elements in array")
    }

    let curr = this.length, min = this.length - size
    let rand

    while (curr !== min) {
      rand = Math.floor(Math.random() * curr)
      curr -= 1
      this._swap(curr, rand)
    }

    return this
  }

  // in-place swapping of two elements in the array
  // at indices x and y respectively
  _swap(x, y) {
    let tmp = this[x]
    this[x] = this[y]
    this[y] = tmp
  }

但是,如果我这样做,我将无法使用带有大量参数的扩展运算符,如下所示:

let integers = Array.from({length: 100000}, (d, i) => i))
let ints = new RandomArray(...integers)      // throws RangeError: Maximum call stack size exceeded

所以我决定尝试修改构造函数以采用单个列表而不是通常的可变参数:

class RandomArrayIfAtFirstYouDontSucceed extends Array {
  constructor(lst) {
    super()
    for (let item of lst) super.push(item)
  }

  ...
}

这似乎工作得很好,直到稍后,当这种情况发生时:

let integers = Array.from({length: 100000}, (d, i) => i))
let ints = new RandomArrayIfAtFirstYouDontSucceed(integers)  // no more range error, yay!
ints.length         // prints out 100000, yay!
ints.slice(88)      // but now this throws TypeError: lst[Symbol.iterator] is not a function

我认为 super() this 做了一些奇怪的事情,这在某种程度上破坏了迭代器协议(protocol),但似乎有很多关于扩展 native 数组的警告,其中一些我不太明白。有人可以帮忙解释一下吗?

顺便说一句,我正在使用 Node v10.11.0 和 Babel 7.1.2。

最佳答案

if I do this, I'm unable to use the spread operator with a lot of arguments, like so:

let integers = Array.from({length: 100000}, (d, i) => i))
let ints = new RandomArray(...integers)    

是的,您永远无法将扩展语法与大量参数一起使用 - 它们只是无法全部放入堆栈中。这与您的 RandomArray 类无关。

不必修改构造函数使其与 new Array(length) 签名约定冲突,只需使用

let integers = RandomArray.from({length: 10000}, (_, i) => i);
console.log(integers.length);
console.log(integers.slice(0, 88));

关于javascript - 扩展内置数组,super() 的行为很奇怪,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52630987/

相关文章:

javascript - React Native 中的 Firebase 可调用函数

javascript - jquery every() 函数不适用于输入字段

javascript - 验证我的代码 json

javascript - 使用 map 创建 HTML ReactJS

javascript - 在 goBack() react 路由器 v4 之前检查历史记录之前的位置

javascript - 使用 Jest 测试 ES6 类会抛出 'not a constructor' 错误

javascript - 客户端上的格式化日期时间会在表单发布上发送默认日期值

javascript - 使用 vscode 时是否应该为 es6 项目提交 typings 文件夹?

javascript - 我如何引用一个以字符串形式命名的类?

JavaScript ES6 装饰器模式