【问题标题】:override forEach to iterate over an object attribute覆盖 forEach 以迭代对象属性
【发布时间】:2021-06-20 01:08:21
【问题描述】:

我目前有一个对象,其中包含一个可以迭代的数组。

====== 第一步 =====

迭代对象的属性而不是对象本身

我想知道是否有使用方法:

const obj = new YMap();
obj.forEach(...);

而不是

const obj = new YMap();
obj.map.forEach();

编辑:来自 VLAZ 评论,我可以添加:

this.forEach = function(f) { this.maps.forEach(f);}

在我的构造函数中,我的 forEach 迭代了我的 maps 属性 对象而不是我的对象本身。

===== 第二步 =====

避免 forEach 重叠解析 Map/List/Array 类型的对象属性

通过扩展,如果我在我的对象上增加一点复杂性,使其没有数组而是列表数组,有没有办法:

const obj = new YMap();
obj.forEach(...);

而不是

const obj = new YMap();
obj.maps.foreach( function(map) { 
    map.forEach( function(item) {
        ...
    }
});

换个说法,我想知道是否有一种方法可以让我拥有这种数据结构:

{
    maps : [
        [ 'A', 'B' ],
        [ 'C', 'D' ],
        [ 'E', 'F' ]
    ]
}

我可以在哪里使用代码:

 obj.forEach(function(item) { console.log(item) });

那会输出:

A B C D E F

不必遍历数组的数组,然后使用复叠的 forEach 遍历每个数组的项

我的对象如下所示:

function YMap() {
    this.maps = [new HashMap()];

    Object.defineProperty(YMap.prototype, 'length', {get: function() {
        ...
    }});
}

YMap.prototype.add = function() {...}

YMap.prototype.get = function() {...}

[...]

module.exports = YMap;

【问题讨论】:

  • Object.keys() + Array.prototype.forEach()
  • 您可以使用 obj.forEach(...); 在您的对象上定义它。无法自动使该方法可用执行您希望它执行的操作(遍历this.maps?)。 obj.map 是什么?
  • @YevgenGorbunkov 我认为 OP 只想迭代一个属性,而不是全部。
  • 您可以定义一个迭代器方法并使用 for..of 循环:*.com/questions/28739745/…
  • @VLAZ 是的,我想知道我是否可以添加一个快捷方式,在属性上隐式使用我的 forEach 而不必使用 myObj.attr.forEach(...)

标签: javascript foreach attributes


【解决方案1】:

您可以创建自定义迭代以循环到对象上。我在 Symbol.iterator 属性的帮助下创建了一个使用基于类的方法。

class YMap {
  constructor() {
    this.maps = [];
  }

  [Symbol.iterator]() {
    let index = 0;
    const that = this;
    return {
      next() {
        let value = undefined;
        let done = true;
        if (index < that.maps.length) {
          value = [...that.maps[index++]].join(" ")
          done = false;
        }
        return {
          value,
          done
        };
      }
    };
  }
  add(item) {
    this.maps.push(item);
  }
}

const obj = new YMap();
obj.add([23, 21]);
obj.add([25, 29]);
for (let c of obj) {
  console.log(c, );
}

【讨论】: