开发者问题收集

在 JavaScript 中创建迭代器时,数组未传递给 next() 方法

2021-09-03
61

我正在自学编码,学习 Java Script。我正在研究一本书上的一个问题,我需要为自定义对象创建一个迭代器,它的作用类似于 Set。

当我想访问我已设置的用于保存 next() 方法中数据的数组时,我收到以下错误:

未捕获的 TypeError:无法读取未定义的属性“length” at Object.next (testerBook.js:34) at testerBook.js:83

在 next() 方法中,它将数组视为未定义。

代码如下:

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

  add(value) {
    if (!this.values.includes(value)) {
      this.values.push(value);
    }
  }

  delete(value) {
    if (this.values.includes(value)) {
      this.values = this.values.filter(e => e !== value);
    }
  }

  has(value) {
    return this.values.includes(value);
  }

  [Symbol.iterator]() {

    let count = 0;
    let nvalues = this.values;
    console.log('nvalues is ', nvalues);

    return {
      next() {
        console.log('In next in iterator ', this.nvalues);
        //try the ++ count afterwards
        if (count === this.values.length - 1) {
          return {
            value: undefined,
            done: true
          };
        } else {
          count++;
          return {
            value: this.values[count - 1],
            done: false
          };
        }

      }
    }
  }

  static from(newValues) {
    let group = new Group();
    for (let value of newValues) {
      if (!group.has(value)) {
        group.add(value);
      }
    }
    return group;
  }

}


let group = Group.from([1, 2, 3, 4, 3, 2, 1, 5]);
console.log(group.values);
for (let value of group) {
  console.log(value);
}

我希望这是我没有看到的简单内容。任何帮助都将不胜感激!

2个回答

this 未传递到 next 函数中。您可以使用箭头函数隐式传递它。

此外,迭代器提前结束,将 if (count === this.values.length - 1) { 更改为 if (count === this.values.length) {

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

    add(value) {
        if (!this.values.includes(value)) {
            this.values.push(value);
        }
    }

    delete(value) {
        if (this.values.includes(value)) {
            this.values = this.values.filter(e => e !== value);
        }
    }

    has(value) {
        return this.values.includes(value);
    }

    [Symbol.iterator]() {
        
        let count = 0;
        let nvalues = this.values;
        console.log('nvalues is ', nvalues);

        return {
            next: () => {
                console.log('In next in iterator ', JSON.stringify(this,null,2));
                //try the ++ count afterwards
                if (count === this.values.length) {
                    return { value: undefined, done: true };
                } else {
                    count++;
                    return { value: this.values[count - 1], done: false };
                }

            }
        }
    }
    
    static from(newValues) {
      let group = new Group();
      for (let value of newValues) {
        if (!group.has(value)) {
          group.add(value);
        }
      }
      return group;
    }
}

let group = Group.from([1, 2, 3, 4, 3, 2, 1, 5]);
console.log(group.values);
for (let value of group) {
  console.log(value);
}
JBaczuk
2021-09-03

this 在传统闭包中无法捕获。

您可以使用 nvalues 局部变量,就像使用 count 一样。

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

  add(value) {
    if (!this.values.includes(value)) {
      this.values.push(value);
    }
  }

  delete(value) {
    if (this.values.includes(value)) {
      this.values = this.values.filter(e => e !== value);
    }
  }

  has(value) {
    return this.values.includes(value);
  }

  [Symbol.iterator]() {

    let count = 0;
    let nvalues = this.values;
    console.log('nvalues is ', nvalues);

    return {
      next() {
        console.log('In next in iterator ', this.nvalues);
        //try the ++ count afterwards
        if (count === nvalues.length - 1) {
          return {
            value: undefined,
            done: true
          };
        } else {
          count++;
          return {
            value: nvalues[count - 1],
            done: false
          };
        }

      }
    }
  }

  static from(newValues) {
    let group = new Group();
    for (let value of newValues) {
      if (!group.has(value)) {
        group.add(value);
      }
    }
    return group;
  }

}


let group = Group.from([1, 2, 3, 4, 3, 2, 1, 5]);
console.log(group.values);
for (let value of group) {
  console.log(value);
}
Barmar
2021-09-03