可以在ES5 JavaScript中实现一个用于对象的键的懒惰迭代器,而无需立即将对象的所有键加载到内存中



我想编写一个ES5 JavaScript函数(即没有生成器或Symbol.iterator),该功能可以完成以下生成器函数在ES6中所做的工作。

function *keys(o) {
  for (let key in o)
    yield key
}

我想返回一个懒惰的迭代器,而不会一次将所有键加载到内存中>,因此Object.keys不在桌子上,因为它返回了键的数组。但是,我似乎无法弄清楚如何做。

我变得绝望了,所以我开始研究发电机如何被转录为不支持它们的JavaScript版本。如果将上面的发电机函数输入到Facebook的再生器中,则将获得以下输出:

var _marked =
/*#__PURE__*/
regeneratorRuntime.mark(keys);
function keys(o) {
  var key;
  return regeneratorRuntime.wrap(function keys$(_context) {
    while (1) {
      switch (_context.prev = _context.next) {
        case 0:
          _context.t0 = regeneratorRuntime.keys(o);
        case 1:
          if ((_context.t1 = _context.t0()).done) {
            _context.next = 7;
            break;
          }
          key = _context.t1.value;
          _context.next = 5;
          return key;
        case 5:
          _context.next = 1;
          break;
        case 7:
        case "end":
          return _context.stop();
      }
    }
  }, _marked, this);
}

阅读了此输出后,我认为regeneratorRuntime.keys的实现可能会容纳答案,但是看来此功能立即将所有键加载到内存中:

exports.keys = function(object) {
  var keys = [];
  for (var key in object) {
    keys.push(key);
  }
  keys.reverse();
  // Rather than returning an object with a next method, we keep
  // things simple and return the next function itself.
  return function next() {
    while (keys.length) {
      var key = keys.pop();
      if (key in object) {
        next.value = key;
        next.done = false;
        return next;
      }
    }
    // To avoid creating an additional object, we just hang the .value
    // and .done properties off the next function object itself. This
    // also ensures that the minifier will not anonymize the function.
    next.done = true;
    return next;
  };
};

有什么想法?

不,没有办法创建懒惰属性迭代器。ES6具有Reflect.enumerate,生成器功能允许您写入keys助手,但是在ES5中,没有这样的设施 - 鉴于ES5没有任何迭代器概念,这并不奇怪。

最新更新