【问题标题】:Custom Iterator for Number Prototype in JSJS中数字原型的自定义迭代器
【发布时间】:2018-07-31 07:50:51
【问题描述】:

最近我了解了 JS 迭代器,在 for( of ) 循环中使用。由于在 JS 中甚至原语都有一个原型,我想知道是否可以扩展 Number 原型,以便以下是一个有效的表达式:

for(let i of 10) console.log(i); //0 1 2 3 4 5 6 7 8 9

显然这仅适用于整数,但有没有办法实现呢?

希望有,但我无法自己创建这个,因为我是 JS 的这一部分的新手......

【问题讨论】:

    标签: javascript for-loop iterator prototype


    【解决方案1】:

    您可以将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; }

    【讨论】:

      【解决方案2】:

      当然,只要定义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)是非常不好的做法 - 最好找到另一种方法来完成你想要完成的任何事情,如果一切皆有可能。

      【讨论】:

      • 嗯,我知道这是不好的做法,而且我不会经常使用它,它更像是一个 JS 实验,试图尝试一些新的东西 :)
      【解决方案3】:

      您可以通过定义一个初始值(在本例中为 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)
      }

      【讨论】:

        【解决方案4】:

        感谢其他答案,我现在能够创建一个有点全面的原型扩展,支持负数和验证...

        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]);

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2013-02-17
          • 2015-02-04
          • 2019-06-03
          • 2010-10-24
          • 2016-06-18
          • 2018-05-13
          相关资源
          最近更新 更多