Интересно, что люди в этих ответах касались как Object.keys()
, так и for...of
, но никогда не объединяли их:
var map = {well:'hello', there:'!'};
for (let key of Object.keys(map))
console.log(key + ':' + map[key]);
Вы не можете просто for...of
и Object
, потому что это не итератор, а for...index
или .forEach()
с Object.keys()
уродлив / неэффективен.
Я рад, что большинство людей воздерживаются от for...in
(с или без проверки .hasOwnProperty()
), поскольку это также немного грязно, поэтому, кроме моего ответа выше, я здесь, чтобы сказать ...
Вы можете сделать обычные ассоциации объектов итеративными! Вести себя так же, как Map
с непосредственным использованием фантазии for...of
DEMO работает в Chrome и FF (я полагаю, только ES6)
var ordinaryObject = {well:'hello', there:'!'};
for (let pair of ordinaryObject)
//key:value
console.log(pair[0] + ':' + pair[1]);
//or
for (let [key, value] of ordinaryObject)
console.log(key + ':' + value);
Пока вы включите мою прокладку ниже:
//makes all objects iterable just like Maps!!! YAY
//iterates over Object.keys() (which already ignores prototype chain for us)
Object.prototype[Symbol.iterator] = function() {
var keys = Object.keys(this)[Symbol.iterator]();
var obj = this;
var output;
return {next:function() {
if (!(output = keys.next()).done)
output.value = [output.value, obj[output.value]];
return output;
}};
};
Без необходимости создавать настоящий объект Map, который не имеет приятного синтаксического сахара.
var trueMap = new Map([['well', 'hello'], ['there', '!']]);
for (let pair of trueMap)
console.log(pair[0] + ':' + pair[1]);
На самом деле, с помощью этой прокладки, если вы все еще хотели воспользоваться другими функциями Map (не объединяя их все), но все еще хотели использовать аккуратную нотацию объектов, поскольку объекты теперь итерируемы, вы можете теперь просто сделать Map от этого!
//shown in demo
var realMap = new Map({well:'hello', there:'!'});
Для тех, кто не любит шимить или вообще возиться с prototype
, не стесняйтесь вместо этого делать функцию в окне, вызывая ее как getObjIterator()
затем;
//no prototype manipulation
function getObjIterator(obj) {
//create a dummy object instead of adding functionality to all objects
var iterator = new Object();
//give it what the shim does but as its own local property
iterator[Symbol.iterator] = function() {
var keys = Object.keys(obj)[Symbol.iterator]();
var output;
return {next:function() {
if (!(output = keys.next()).done)
output.value = [output.value, obj[output.value]];
return output;
}};
};
return iterator;
}
Теперь вы можете просто вызывать ее как обычную функцию, больше ничего не влияет
var realMap = new Map(getObjIterator({well:'hello', there:'!'}))
или
for (let pair of getObjIterator(ordinaryObject))
Нет причин, по которым это не сработает.
Добро пожаловать в будущее.