我正在尝试扩展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。
答案 0 :(得分:1)
如果执行此操作,则无法使用带有很多参数的spread运算符,如下所示:
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));