是否可以在ES5 JavaScript中实现对象键的延迟迭代器,而无需一次将对象的所有键加载到内存中?

问题描述 投票:0回答:1

我想写一个ES5 JavaScript函数(即没有生成器或Symbol.iterator)来完成以下生成器函数在ES6中的作用:

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

我想返回一个懒惰的迭代器,而不是立即将所有的密钥加载到内存中,所以Object.keys离开了表,因为它返回了一个键的数组。但是,我似乎无法弄明白该怎么做。

我变得绝望,所以我开始研究如何将生成器转换为不支持它们的JavaScript版本。如果您将上面的生成器函数输入到Facebook's Regenerator中,则会得到以下输出:

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

有任何想法吗?

javascript arrays object iterator generator
1个回答
0
投票

不,没有办法创建一个惰性属性迭代器。 ES6有Reflect.enumerate,生成器函数允许你编写keys助手,但在ES5中没有这样的工具存在 - 假设ES5没有任何迭代器概念,那就不足为奇了。

© www.soinside.com 2019 - 2024. All rights reserved.