I want to write a ES5 JavaScript function (ie without generators or Symbol.iterator
) that accomplishes what the following generator function does in ES6:
function *keys(o) {
for (let key in o)
yield key
}
I want to return a lazy iterator without loading all of the keys into memory at once , so Object.keys
is off the table since it returns an array of the keys. However, I can't seem to figure out how to do it.
I was getting desperate so I started looking into how generators are transpiled into versions of JavaScript which do not support them. If you input the generator function above into Facebook's Regenerator , you get the following output:
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);
}
After reading through this output I thought that the implementation of regeneratorRuntime.keys
might hold the answer, but it appears that this function loads all of the keys into memory at once:
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;
};
};
Any ideas?
No, there is no way to create a lazy property iterator. ES6 had Reflect.enumerate
, and generator functions allow you to write that keys
helper, but in ES5 no such facility exists - given that ES5 did not have any iterator concept, that's not surprising.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.