É pessoas interessantes nestas respostas tocaram em ambos Object.keys()
e for...of
mas nunca combinou-os:
var map = {well:'hello', there:'!'};
for (let key of Object.keys(map))
console.log(key + ':' + map[key]);
Você pode não apenas for...of
um Object
, porque não é um iterador, e for...index
ou .forEach()
ing o Object.keys()
é feio / ineficiente.
Fico feliz que a maioria das pessoas se abstenha de for...in
(com ou sem verificação .hasOwnProperty()
), pois isso também é um pouco confuso, então, além da minha resposta acima, estou aqui para dizer ...
Você pode fazer associações de objetos comuns iterarem! Comportando-se como Map
s com o uso direto da for...of
DEMO chique trabalhando no Chrome e no FF (presumo apenas o 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);
Contanto que você inclua meu calço abaixo:
//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;
}};
};
Sem ter que criar um objeto de mapa real que não tenha o bom açúcar sintático.
var trueMap = new Map([['well', 'hello'], ['there', '!']]);
for (let pair of trueMap)
console.log(pair[0] + ':' + pair[1]);
De fato, com esse calço, se você ainda deseja tirar proveito das outras funcionalidades do Map (sem compor todas), mas ainda deseja usar a notação de objeto, uma vez que os objetos agora são iteráveis, agora você pode fazer um mapa a partir dele!
//shown in demo
var realMap = new Map({well:'hello', there:'!'});
Para quem não gosta de brincar ou mexer prototype
em geral, sinta-se à vontade para fazer a função na janela, chamando-a de algo parecido com getObjIterator()
isso;
//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;
}
Agora você pode chamá-lo como uma função comum, nada mais é afetado
var realMap = new Map(getObjIterator({well:'hello', there:'!'}))
ou
for (let pair of getObjIterator(ordinaryObject))
Não há razão para que isso não funcione.
Bem vindo ao futuro.