Mogelijk duplicaat: Iterate over Object Literal Values
Ik heb een object in JavaScript:
var object = someobject;
Object { aaa=true, bbb=true, ccc=true }
Hoe kan ik elk voor dit gebruiken?
object.each(function(index, value)) {
console.log(value);
}
Werkt niet.
Een javascript Object heeft geen standaard .each functie. jQuery levert een functie. Zie http://api.jquery.com/jQuery.each/. Onderstaande zou moeten werken
$.each(object, function(index, value) {
console.log(value);
});
Een andere optie zou zijn om vanilla Javascript te gebruiken met de Object.keys()
en de Array .map()
functies zoals deze
Object.keys(object).map(function(objectKey, index) {
var value = object[objectKey];
console.log(value);
});
Zie https://developer.mozilla.org/nl/docs/Web/JavaScript/Reference/Global_Objects/Object/keys en https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map
Deze zijn meestal beter dan het gebruik van een vanilla Javascript for-loop, tenzij je echt de implicaties begrijpt van het gebruik van een normale for-loop en het nut inziet van zijn specifieke karakteristieken zoals looping over de property chain.
Maar meestal werkt een for-loop niet beter dan jQuery
of Object.keys().map()
. Ik zal hieronder ingaan op twee potentiële problemen met het gebruik van een gewone for-lus.
Juist, dus ook aangegeven in andere antwoorden, een gewoon Javascript alternatief zou zijn
for(var index in object) {
var attr = object[index];
}
Er zijn twee potentiële problemen met dit:
1 . U wilt controleren of het attribuut dat u vindt van het object zelf is en niet van hogerop in de prototype keten. Dit kunt u controleren met de hasOwnProperty
functie, zoals hieronder
for(var index in object) {
if (object.hasOwnProperty(index)) {
var attr = object[index];
}
}
Zie https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwnProperty voor meer informatie.
De jQuery.each
en Object.keys
functies zorgen hier automatisch voor.
2 . Een ander potentieel probleem met een gewone for-lus is dat van scope en non-closures. Dit is een beetje ingewikkeld, maar neem bijvoorbeeld de volgende code. We hebben een aantal knoppen met id's button0, button1, button2 etc, en we willen er een onclick op zetten en een console.log
doen zoals dit:
<button id='button0'>click</button>
<button id='button1'>click</button>
<button id='button2'>click</button>
var messagesByButtonId = {"button0" : "clicked first!", "button1" : "clicked middle!", "button2" : "clicked last!"];
for(var buttonId in messagesByButtonId ) {
if (messagesByButtonId.hasOwnProperty(buttonId)) {
$('#'+buttonId).click(function() {
var message = messagesByButtonId[buttonId];
console.log(message);
});
}
}
Als we na een tijdje op een van de knoppen klikken, krijgen we altijd "clicked last!" in de console, en nooit "clicked first!" of "clicked middle!". Waarom? Omdat op het moment dat de onclick functie wordt uitgevoerd, het berichtenByButtonId[buttonId]
weergeeft met behulp van de buttonId
variabele op dat moment. En omdat de lus op dat moment is afgelopen, zal de buttonId
variabele nog steeds "button2" zijn (de waarde die het had tijdens de laatste lus iteratie), en dus berichtenByButtonId[buttonId]
zal berichtenByButtonId["button2"]
zijn, d.w.z. "laatst geklikt!".
Zie https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures voor meer informatie over closures. Vooral het laatste deel van die pagina dat ons voorbeeld behandelt.
Nogmaals, jQuery.each
en Object.keys().map()
lossen dit probleem automatisch voor ons op, omdat het ons voorziet van een functie(index, waarde)
(die closure heeft) zodat we veilig zijn om zowel index als waarde te gebruiken en er zeker van zijn dat ze de waarde hebben die we verwachten.
var object = { "a": 1, "b": 2};
$.each(object, function(key, value){
console.log(key + ": " + object[key]);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
//output
a: 1
b: 2