【问题标题】:Accessing 'this' inside JS iterator's next() method? [duplicate]在 JS 迭代器的 next() 方法中访问“this”? [复制]
【发布时间】:2019-01-17 20:00:20
【问题描述】:

我目前正在研究Eloquent JavaScript's object assignments,我想知道是否有任何方法可以在迭代器的next() 方法中使用this(请参阅代码)

class Group {
  constructor() {
    this.members = [];
  }

  add(member) {
    if (this.has(member)) return;
    this.members.push(member);
  }

  delete(member) {
    if (!this.has(member)) return;
    this.members.splice(this.members.indexOf(member), 1);
  }

  has(member) {
    return this.members.indexOf(member) !== -1
  }

  static from(iterable) {
    const group = new Group();
    for (const element of iterable) {
      group.add(element);
    }

    return group;
  }

  [Symbol.iterator]() {
    let current = 0;
    let last = this.members.length - 1;

    const that = this;

    return {
      next() {
        if (current <= last) {
          return {
            done: false,
            value: that.members[current++]
          }
        } else return { done:true }
      }
    }
  }
}

for (let value of Group.from(["a", "b", "c"])) {
  console.log(value);
}

如您所见,我正在使用这种奇怪的const that = this 模式。有什么办法可以摆脱它吗?除了使用箭头函数并将迭代器提取到单独的类之外,如解决方案中所建议的那样。

【问题讨论】:

    标签: javascript iterator


    【解决方案1】:

    最好的方法是在构造函数部分实现对象的默认迭代器,并使用yield* expression 委托给数组this.members 的另一个生成器。

    constructor() {
        this.members = [];
        this[Symbol.iterator] = function* () {
            yield* this.members;
        }
    }
    

    class Group {
        constructor() {
            this.members = [];
            this[Symbol.iterator] = function* () {
                yield* this.members;
            }
        }
    
        add(member) {
            if (this.has(member)) return;
            this.members.push(member);
        }
    
        delete(member) {
            if (!this.has(member)) return;
            this.members.splice(this.members.indexOf(member), 1);
        }
    
        has(member) {
            return this.members.indexOf(member) !== -1
        }
    
        static from(iterable) {
            const group = new Group();
            for (const element of iterable) {
                group.add(element);
            }
            return group;
        }
    }
    
    for (let value of Group.from(["a", "b", "c"])) {
        console.log(value);
    }
    .as-console-wrapper { max-height: 100% !important; top: 0; }

    【讨论】:

    • 这其实是个不错的方法!
    【解决方案2】:

    你可以使用箭头功能

    class Group {
      constructor() {
        this.members = [];
      }
    
      add(member) {
        if (this.has(member)) return;
        this.members.push(member);
      }
    
      delete(member) {
        if (!this.has(member)) return;
        this.members.splice(this.members.indexOf(member), 1);
      }
    
      has(member) {
        return this.members.indexOf(member) !== -1
      }
    
      static from(iterable) {
        const group = new Group();
        for (const element of iterable) {
          group.add(element);
        }
    
        return group;
      }
    
      [Symbol.iterator]() {
        let current = 0;
        let last = this.members.length - 1;
        return {
          next: () => {
            if (current <= last) {
              return {
                done: false,
                value: this.members[current++]
              }
            } else return { done:true }
          }
        }
      }
    }
    
    for (let value of Group.from(["a", "b", "c"])) {
      console.log(value);
    }

    【讨论】:

    • 箭头函数中没有this
    • @zer00ne 他要求摆脱在 sn-p 中发生的const that = this;
    • next: () =&gt; { if (current &lt;= last) { return { done: false, value: this.members[current++] }...
    • 是吗?使用箭头函数this 将引用类(他想要的)
    • 嗯,控制台输出不言自明。 this 是在其中执行 group[Symbol.iterator] 以获得 for ... of 循环所需的迭代器的上下文:正确的类实例。
    猜你喜欢
    • 1970-01-01
    • 2012-06-19
    • 1970-01-01
    • 1970-01-01
    • 2018-05-20
    • 1970-01-01
    • 2023-01-23
    • 2015-06-16
    相关资源
    最近更新 更多