最近我了解了 JS 迭代器,它被用在
for( of )
循环中。由于在 JS 中,即使基元也有原型,我想知道是否可以扩展 Number 原型,以便以下内容成为有效的表达式:
for(let i of 10) console.log(i); //0 1 2 3 4 5 6 7 8 9
显然这仅适用于整数,但是有没有办法实现呢?
希望有,但我无法自己创建这个,因为我对 JS 的这一部分很陌生......
Generator
的 Symbol.iterator
作为 Number
的原型。
Number.prototype[Symbol.iterator] = function* () {
for (var i = 0; i < this; i++) {
yield i;
}
};
console.log([...10]);
.as-console-wrapper { max-height: 100% !important; top: 0; }
当然,只需定义
Number.prototype[Symbol.iterator]
:
Number.prototype[Symbol.iterator] = function() {
let currentNum = 0;
return {
next: () => (
currentNum == this
? { done: true }
: {
value: currentNum++,
done: false
}
)
}
}
for (const i of 10) console.log(i);
但是改变内置对象(如全局
Number
)是非常不好的做法 - 如果可能的话,最好找到另一种方法来完成你想要完成的任何事情。
您可以通过定义一个初始值(在本例中为 0)并在yield 循环中递增该值直到该值等于数字来实现此目的:
Number.prototype[Symbol.iterator] = function* () {
var value = 0;
//< or <= depending on what you are expecting as the end number
while(value <= this){
//yield the value and increment
yield value++;
}
};
for (let i of 10) {
console.log("num", i)
}
感谢其他答案,我现在能够创建一个稍微全面的原型扩展,支持负数和验证......
Number.prototype[Symbol.iterator] = function*(){
if(!Number.isInteger(this.valueOf()))
throw new TypeError("Only integers can be iterated over.");
if(this>0)
for(let i=0;i<this;i++)
yield i;
if(this<0)
for(let i=0;i>this;i--)
yield i;
};
console.log([...5]);
console.log([...-5]);
console.log([...0]);
console.log([...1.5]);
另一种方法是使用无槽数组实例的
keys
迭代器:
Number.prototype[Symbol.iterator] = function () {
const iter = Array(Math.abs(this)).keys();
return this < 0 ? iter.map(x => -x) : iter;
}
console.log([...5]);
console.log([...-5]);
console.log([...0]);
console.log([...1.5]); // Error: invalid array length