Javascript 扩展内置数组时,super()的行为异常
我试图扩展JS的本机Javascript 扩展内置数组时,super()的行为异常,javascript,ecmascript-6,es6-class,Javascript,Ecmascript 6,Es6 Class,我试图扩展JS的本机数组,这样我就有了一个实现随机洗牌的数组,如下所示: 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)
数组
,这样我就有了一个实现随机洗牌的数组,如下所示:
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
}
但是,如果我这样做,我就无法在大量参数中使用spread运算符,如下所示:
let integers = Array.from({length: 100000}, (d, i) => i))
let ints = new RandomArray(...integers) // throws RangeError: Maximum call stack size exceeded
let integers = Array.from({length: 100000}, (d, i) => i))
let ints = new RandomArray(...integers)
因此,我决定尝试修改构造函数以采用单个列表,而不是通常的可变参数:
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()
对这个做了一些奇怪的事情,这在某种程度上破坏了迭代器协议,但似乎有很多关于扩展本机数组的警告,其中一些我不太理解。有人能解释一下吗
顺便说一句,我使用的是节点v10.11.0和巴贝尔7.1.2
如果我这样做,我将无法使用带有大量参数的spread运算符,如下所示:
let integers = Array.from({length: 100000}, (d, i) => i))
let ints = new RandomArray(...integers) // throws RangeError: Maximum call stack size exceeded
let integers = Array.from({length: 100000}, (d, i) => i))
let ints = new RandomArray(...integers)
是的,您永远无法将扩展语法与许多参数一起使用-它们只是不能全部放在堆栈中。这与您的RandomArray
类无关
与其修改构造函数使其与新数组(长度)
签名契约冲突,不如使用
let integers = RandomArray.from({length: 10000}, (_, i) => i);
console.log(integers.length);
console.log(integers.slice(0, 88));
啊。我应该意识到,RandomArray
也将从Array
继承from
方法。