在JS迭代器的next()方法中访问"this"?



我目前正在处理 Eloquent JavaScript 的对象赋值,我想知道是否有任何方法可以在迭代器的 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模式。有什么办法可以摆脱它吗?除了使用箭头函数并将迭代器提取到单独的类,如解决方案中所示。

最排序的方式可能是在构造函数部分中实现对象的默认迭代器,并使用yield*表达式委托给数组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; }

您可以使用箭头函数

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

最新更新