【发布时间】:2018-10-03 15:46:14
【问题描述】:
我正在尝试扩展 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 做了一些奇怪的事情,这在某种程度上与迭代器协议有关,但似乎有很多关于扩展本机数组的警告,其中一些我真的不明白。有人可以帮忙解释一下吗?
顺便说一句,我使用的是 Node v10.11.0 和 Babel 7.1.2。
【问题讨论】:
标签: javascript ecmascript-6 es6-class