Ik heb een JavaScript-object zoals het volgende:
var p = {
"p1": "value1",
"p2": "value2",
"p3": "value3"
};
Nu wil ik alle p
-elementen doorlopen (p1
, p2
, p3
…) En krijgen hun sleutels en waarden. Hoe kan ik dat doen?
Ik kan het JavaScript-object indien nodig wijzigen. Mijn uiteindelijke doel is om een aantal sleutelwaardeparen te doorlopen en indien mogelijk wil ik het gebruik van eval
vermijden.
Antwoord 1, autoriteit 100%
U kunt de for-in
lus zoals door anderen getoond. Je moet er echter ook voor zorgen dat de sleutel die je krijgt een echte eigenschap van een object is en niet afkomstig is van het prototype.
Hier is het fragment:
var p = {
"p1": "value1",
"p2": "value2",
"p3": "value3"
};
for (var key in p) {
if (p.hasOwnProperty(key)) {
console.log(key + " -> " + p[key]);
}
}
Antwoord 2, autoriteit 26%
Onder ECMAScript 5 kunt u Object.keys()
en Array.prototype.forEach()
:
var obj = { first: "John", last: "Doe" };
Object.keys(obj).forEach(function(key) {
console.log(key, obj[key]);
});
Ecmascript 6 voegt for...of
:
for (const key of Object.keys(obj)) {
console.log(key, obj[key]);
}
Ecmascript 8 voegt Object.entries()
die vermijdt elke waarde op te zoeken in het originele object:
Object.entries(obj).forEach(
([key, value]) => console.log(key, value)
);
U kunt for...of
, destructureren en Object.entries
:
for (const [key, value] of Object.entries(obj)) {
console.log(key, value);
}
Beide Object.keys()
EN Object.entries()
Herstenen in dezelfde volgorde als een for...in
lus maar negeer de prototypeketen . Alleen de eigen traaglijke eigenschappen van het object zijn geïllustreerd.
3, Autoriteit 7%
U moet de voor-in-in-lus
gebruiken
Maar wees heel voorzichtig bij het gebruik van dit soort lus, omdat dit alle eigenschappen langs de prototype keten zal gebruiken.
Gebruik daarom bij het gebruik van for-in-lussen altijd de methode hasOwnProperty
om te bepalen of de huidige eigenschap in iteratie echt een eigenschap is van het object dat u controleert:
for (var prop in p) {
if (!p.hasOwnProperty(prop)) {
//The current property is not a direct property of p
continue;
}
//Do your logic with the property here
}
Antwoord 4
Voorwoord:
- Objecteigenschappen kunnen eigenzijn (de eigenschap bevindt zich op het object zelf) of geërfd(niet op het object zelf, op een van de prototypes).
- Objecteigenschappen kunnen opsombaarof niet-opsombaarzijn. Niet-opsombare eigenschappen worden weggelaten uit veel opsommingen/arrays van eigenschappen.
- Eigenschapsnamen kunnen tekenreeksen of symbolen zijn. Eigenschappen waarvan de namen Symbolen zijn, zijn weggelaten uit veel opsommingen/arrays van eigenschappen.
Hier in 2018 zijn uw opties voor het doorlopen van de eigenschappen van een object (sommige voorbeelden volgen de lijst):
for-in
[MDN, spec] — Een lusstructuur die door de namen van de opsombareeigenschappen van een object loopt, inclusief geërfde eigenschappen, waarvan de namen strings zijnObject.keys
[MDN, spec] — Een functie die een array levert van de namen van de eigen, enumerableeigenschappen van een object waarvan de namen strings zijn.Object.values
[MDN, spec] — Een functie die een array levert van de waardenvan de eigen, enumerableeigenschappen van een object.Object.entries
[MDN spec ] – Een functie verschaffen van een array van namen en waarden eigen , opgesomd eigenschappen (elk item in de array een[name, value]
array).Object.getOwnPropertyNames
[MDN spec ] – Een functie die zorgt voor een serie van de namen van de eigen eigenschappen (zelfs niet-opsombare degenen) van een object waarvan de namen zijn strings.Object.getOwnPropertySymbols
[MDN spec ] – Een functie die zorgt voor een serie van de namen van de eigen eigenschappen (zelfs niet-opsombare degenen) van een object waarvan de namen zijn symbolen.Reflect.ownKeys
[MDN spec ] – Een functie die zorgt voor een serie van de namen van de eigen eigenschappen (zelfs niet-opsombare degenen) van een object, ongeacht of deze namen zijn strings of symbolen.- Als u alleeigenschappen van een object wilt, inclusief niet-opsombare geërfde eigenschappen, moet u een lus gebruiken en
Object.getPrototypeOf
[MDN, spec] en gebruikObject.getOwnPropertyNames
,Object.getOwnPropertySymbols
ofReflect.ownKeys
op elk object in de prototypeketen (voorbeeld onderaan dit antwoord).
Met alle behalve for-in
, zou je een soort looping-constructie op de array gebruiken (for
, for-of
, forEach
, enz.).
Voorbeelden:
for-in
:
Antwoord 5
In ECMAScript 5 heb je een nieuwe benadering in iteratievelden van letterlijk – Object.keys
Meer informatie vindt u op MDN
Mijn keuze is hieronder als een snellere oplossing in huidige versies van browsers (Chrome30, IE10, FF25)
var keys = Object.keys(p),
len = keys.length,
i = 0,
prop,
value;
while (i < len) {
prop = keys[i];
value = p[prop];
i += 1;
}
Je kunt de prestaties van deze aanpak vergelijken met verschillende implementaties op jsperf.com:
Browserondersteuning die u kunt zien op Kangax’s compattabel
Voor de oude browser heb je eenvoudigeen volledigepolyfill
UPD:
prestatievergelijking voor alle meest populaire gevallen in deze vraag op perfjs.info
:
letterlijke iteratie van het object
Antwoord 6
Je kunt het gewoon herhalen als:
for (var key in p) {
alert(p[key]);
}
Houd er rekening mee dat key
niet de waarde van de eigenschap overneemt, het is slechts een indexwaarde.
Antwoord 7
Sinds es2015 steeds populairder wordt, plaats ik dit antwoord, inclusief het gebruik van generator en iterator om soepel door [key, value]
-paren te itereren. Zoals het mogelijk is in andere talen, bijvoorbeeld Ruby.
Ok, hier is een code:
const MyObject = {
'a': 'Hello',
'b': 'it\'s',
'c': 'me',
'd': 'you',
'e': 'looking',
'f': 'for',
[Symbol.iterator]: function*() {
for (const i of Object.keys(this)) {
yield [i, this[i]];
}
}
};
for (const [k, v] of MyObject) {
console.log(`Here is key ${k} and here is value ${v}`);
}
8
Prestaties
Vandaag 2020.03.06 Ik voer tests uit gekozen oplossingen op Chrome V80.0, Safari V13.0.5 en Firefox 73.0.1 op MacOS High Sierra V10.13.6
Conclusies
- Oplossingen op basis van
for-in
(A, B) zijn snel (of snel) voor alle browsers voor grote en kleine objecten - verrassend
for-of
(H) -oplossing is snel op chroom voor kleine en grote objecten - Solutions op basis van expliciete index
i
(J, K) zijn vrij snel op alle browsers voor kleine objecten (voor Firefox ook snel voor grote OJBECTS maar Medium snel op andere browsers) - Oplossingen op basis van iterators (D, E) zijn langzaamst en niet aanbevolen
- Oplossing C is traag voor grote voorwerpen en middellange traag voor kleine objecten
Details
Performance-tests zijn uitgevoerd voor
- Small Object – Met 3 velden – U kunt de test uitvoeren op uw machine hier
- ‘Big’ object – Met 1000 velden – U kunt de test uitvoeren op uw machine hier
Hieronder tafsluitingen presenteert gebruikte oplossingen
9
for(key in p) {
alert( p[key] );
}
Opmerking: u kunt dit boven arrays doen, maar u hanteert ook over de length
en andere eigenschappen.
10
Na alle antwoorden hier te hebben bekeken, is hasOwnProperty niet vereist voor mijn eigen gebruik omdat mijn json-object schoon is; het heeft echt geen zin om extra javascript-verwerking toe te voegen. Dit is alles wat ik gebruik:
for (var key in p) {
console.log(key + ' => ' + p[key]);
// key is key
// value is p[key]
}
Antwoord 11
via prototypemet forEach()die de eigenschappen van de prototypeketenmoeten overslaan:
Object.prototype.each = function(f) {
var obj = this
Object.keys(obj).forEach( function(key) {
f( key , obj[key] )
});
}
//print all keys and values
var obj = {a:1,b:2,c:3}
obj.each(function(key,value) { console.log(key + " " + value) });
// a 1
// b 2
// c 3
Antwoord 12
Het is interessant dat mensen in deze antwoorden zowel Object.keys()
als for...of
hebben aangeraakt, maar ze nooit hebben gecombineerd:
var map = {well:'hello', there:'!'};
for (let key of Object.keys(map))
console.log(key + ':' + map[key]);
Je kunt niet zomaar for...of
een Object
omdat het geen iterator is, en for...index
of .forEach()
het gebruik van Object.keys()
is lelijk/inefficiënt.
Ik ben blij dat de meeste mensen afzien van for...in
(met of zonder het aanvinken van .hasOwnProperty()
), want dat is ook een beetje rommelig, dus anders dan mijn antwoord hierboven, ik ben hier om te zeggen…
U kunt gewone objectsverenigingen maken, itereren! Gedraag je net als Map
s met direct gebruik van de fancy for...of
Demo Werken in Chrome en FF (ik neem alleen aan 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);
Zolang u mijn shim hieronder opneemt:
//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;
}};
};
Zonder een echt kaartobject te maken dat niet de leuke syntactische suiker heeft.
var trueMap = new Map([['well', 'hello'], ['there', '!']]);
for (let pair of trueMap)
console.log(pair[0] + ':' + pair[1]);
In feite, met deze shim, als je nog steeds wilt profiteren van de andere functionaliteit van de kaart (zonder ze allemaal in te schakelen) maar nog steeds wilde het note-objectnotatie gebruiken, omdat objecten nu iespubliek zijn, kun je nu gewoon een kaart maken van het!
//shown in demo
var realMap = new Map({well:'hello', there:'!'});
Voor degenen die niet van shim houden, of in het algemeen niet met prototype
knoeien, voel je vrij om de functie in plaats daarvan in het venster te maken, door het iets te noemen als getObjIterator()
dan;
//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;
}
Nu kun je het gewoon een gewone functie noemen, er wordt verder niets beïnvloed
var realMap = new Map(getObjIterator({well:'hello', there:'!'}))
of
for (let pair of getObjIterator(ordinaryObject))
Er is geen reden waarom dat niet zou werken.
Welkom in de toekomst.
Antwoord 13
var p = {
"p1": "value1",
"p2": "value2",
"p3": "value3"
};
for (var key in p) {
if (p.hasOwnProperty(key)) {
console.log(key + " = " + p[key]);
}
}
<p>
Output:<br>
p1 = values1<br>
p2 = values2<br>
p3 = values3
</p>
Antwoord 14
Je kunt ook Object.keys() gebruiken en de objectsleutels herhalen zoals hieronder om de waarde te krijgen:
var p = {
"p1": "value1",
"p2": "value2",
"p3": "value3"
};
Object.keys(p).forEach((key)=> {
console.log(key +' -> '+ p[key]);
});
Antwoord 15
Object.keys(obj): Array
haalt alle sleutels met tekenreekswaarde op van alle opsombare eigen (niet-overgenomen) eigenschappen.
Het geeft dus dezelfde lijst met sleutels als u van plan bent door elke objectsleutel te testen met hasOwnProperty. Je hebt die extra testoperatie niet nodig dan en Object.keys( obj ).forEach(function( key ){})
zou sneller moeten zijn. Laten we het bewijzen:
var uniqid = function(){
var text = "",
i = 0,
possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
for( ; i < 32; i++ ) {
text += possible.charAt( Math.floor( Math.random() * possible.length ) );
}
return text;
},
CYCLES = 100000,
obj = {},
p1,
p2,
p3,
key;
// Populate object with random properties
Array.apply( null, Array( CYCLES ) ).forEach(function(){
obj[ uniqid() ] = new Date()
});
// Approach #1
p1 = performance.now();
Object.keys( obj ).forEach(function( key ){
var waste = obj[ key ];
});
p2 = performance.now();
console.log( "Object.keys approach took " + (p2 - p1) + " milliseconds.");
// Approach #2
for( key in obj ) {
if ( obj.hasOwnProperty( key ) ) {
var waste = obj[ key ];
}
}
p3 = performance.now();
console.log( "for...in/hasOwnProperty approach took " + (p3 - p2) + " milliseconds.");
Antwoord 16
Alleen JavaScript-code zonder afhankelijkheden:
var p = {"p1": "value1", "p2": "value2", "p3": "value3"};
keys = Object.keys(p); // ["p1", "p2", "p3"]
for(i = 0; i < keys.length; i++){
console.log(keys[i] + "=" + p[keys[i]]); // p1=value1, p2=value2, p3=value3
}
Antwoord 17
In het nieuwste ES-script kun je zoiets als dit doen:
let p = {foo: "bar"};
for (let [key, value] of Object.entries(p)) {
console.log(key, value);
}
Antwoord 18
Hier is een andere methode om een object te doorlopen.
var p = {
"p1": "value1",
"p2": "value2",
"p3": "value3"
};
Object.keys(p).forEach(key => { console.log(key, p[key]) })
Antwoord 19
Een for-of
gebruiken op Object.keys()
Vind ik leuk:
let object = {
"key1": "value1",
"key2": "value2",
"key3": "value3"
};
for (let key of Object.keys(object)) {
console.log(key + " : " + object[key])
}
Antwoord 20
U kunt een eenvoudige functie forEachaan alle objecten toevoegen, zodat u automatisch door elk object kunt bladeren:
Object.defineProperty(Object.prototype, 'forEach', {
value: function (func) {
for (var key in this) {
if (!this.hasOwnProperty(key)) {
// skip loop if the property is from prototype
continue;
}
var value = this[key];
func(key, value);
}
},
enumerable: false
});
Voor die mensen die de “for … in“-methode niet leuk vinden:
Object.defineProperty(Object.prototype, 'forEach', {
value: function (func) {
var arr = Object.keys(this);
for (var i = 0; i < arr.length; i++) {
var key = arr[i];
func(key, this[key]);
}
},
enumerable: false
});
Nu kunt u eenvoudig bellen:
p.forEach (function(key, value){
console.log ("Key: " + key);
console.log ("Value: " + value);
});
Als u geen conflicten wilt krijgen met andere forEach-methoden, kunt u deze een naam geven met uw unieke naam.
Antwoord 21
Meerdere manieren om een object in javascript te herhalen
Gebruik for…inloop
var p = {
"p1": "value1",
"p2": "value2",
"p3": "value3"
};
for (let key in p){
if(p.hasOwnProperty(key)){
console.log(`${key} : ${p[key]}`)
}
}
Antwoord 22
Loops kunnen behoorlijk interessant zijn als je puur JavaScript gebruikt. Het lijkt erop dat alleen ECMA6 (Nieuwe JavaScript-specificatie uit 2015) de lussen onder controle kreeg. Helaas, terwijl ik dit schrijf, worstelen zowel browsers als de populaire geïntegreerde ontwikkelomgeving (IDE) nog steeds met het volledig ondersteunen van de nieuwe toeters en bellen.
Hier ziet u in één oogopslag hoe een JavaScript-objectlus eruitziet vóór ECMA6:
for (var key in object) {
if (p.hasOwnProperty(key)) {
var value = object[key];
console.log(key); // This is the key;
console.log(value); // This is the value;
}
}
Ik weet ook dat dit buiten het bereik van deze vraag valt, maar in 2011 voegde ECMAScript 5.1 de forEach
-methode toe voor alleen arrays, wat in feite een nieuwe verbeterde manier creëerde om door arrays te lussen terwijl er nog steeds geen itereerbare objecten met de oude uitgebreide en verwarrende for
-lus. Maar het vreemde is dat deze nieuwe forEach
-methode break
niet ondersteunt, wat tot allerlei andere problemen heeft geleid.
In principe is er in 2011 geen echt solide manier om JavaScript in een lus te plaatsen, behalve wat veel populaire bibliotheken (jQuery, Underscore, etc.) besloten opnieuw te implementeren.
Vanaf 2015 hebben we nu een betere kant-en-klare manier om elk objecttype (inclusief arrays en strings) te herhalen (en te breken). Dit is hoe een lus in JavaScript er uiteindelijk uit zal zien wanneer de aanbeveling mainstream wordt:
for (let [key, value] of Object.entries(object)) {
console.log(key); // This is the key;
console.log(value); // This is the value;
}
Houd er rekening mee dat de meeste browsers de bovenstaande code vanaf 18 juni 2016 niet meer ondersteunen. Zelfs in Chrome moet je deze speciale vlag inschakelen om het te laten werken: chrome://flags/#enable-javascript-harmony
Totdat dit de nieuwe standaard wordt, kan de oude methode nog steeds worden gebruikt, maar er zijn ook alternatieven in populaire bibliotheken of zelfs lichtgewicht alternatievenvoor degenen die geen van deze bibliotheken gebruiken.
Antwoord 23
In ES6 hebben we bekende symbolen om enkele eerder interne methoden bloot te leggen, je kunt het gebruiken om te definiëren hoe iterators voor dit object werken:
var p = {
"p1": "value1",
"p2": "value2",
"p3": "value3",
*[Symbol.iterator]() {
yield *Object.keys(this);
}
};
[...p] //["p1", "p2", "p3"]
Hiermee geeft u hetzelfde resultaat als gebruik van … in ES6-lus.
for(var key in p) {
console.log(key);
}
Maar het is belangrijk om de mogelijkheden te kennen die u nu hebt gebruikt ES6!
24
Ik zou dit doen in plaats van het controleren van obj.hasOwnerProperty
binnen elke for...in
lus.
var obj = {a : 1};
for(var key in obj){
//obj.hasOwnProperty(key) is not needed.
console.log(key);
}
//then check if anybody has messed the native object. Put this code at the end of the page.
for(var key in Object){
throw new Error("Please don't extend the native object");
}
25
var p =[{"username":"ordermanageadmin","user_id":"2","resource_id":"Magento_Sales::actions"},
{"username":"ordermanageadmin_1","user_id":"3","resource_id":"Magento_Sales::actions"}]
for(var value in p) {
for (var key in value) {
if (p.hasOwnProperty(key)) {
console.log(key + " -> " + p[key]);
}
}
}
26
Een goede manier voor looping op een traaglijk JavaScript-object dat geweldig kan zijn en gebruikelijk voor reactersnelheden gebruikt Object.keys
of Object.entries
met behulp van map
Functie. Zoals hieronder:
// assume items:
const items = {
first: { name: 'phone', price: 400 },
second: { name: 'tv', price: 300 },
third: { name: 'sofa', price: 250 },
};
Voor looping en toon wat UI op ReactJS
zoals hieronder:
~~~
<div>
{Object.entries(items).map(([key, ({ name, price })]) => (
<div key={key}>
<span>name: {name}</span>
<span>price: {price}</span>
</div>
))}
</div>
Eigenlijk gebruik ik de destructuring-opdracht twee keer, eenmaal voor het verkrijgen van key
eenmaal voor het verkrijgen van name
EN price
.
27
Als u wilt herhalen over Niet-traaglijke eigenschappen ook, u kunt Object.getOwnPropertyNames(obj)
om een reeks van alle eigendommen (traagbaar of niet) rechtstreeks op een bepaald object te retourneren.
var obj = Object.create({}, {
// non-enumerable property
getFoo: {
value: function() { return this.foo; },
enumerable: false
}
});
obj.foo = 1; // enumerable property
Object.getOwnPropertyNames(obj).forEach(function (name) {
document.write(name + ': ' + obj[name] + '<br/>');
});
28
Als iemand moet worden uitgevoerd door ArrayObjects met Conditie :
var arrayObjects = [{"building":"A", "status":"good"},{"building":"B","status":"horrible"}];
for (var i=0; i< arrayObjects.length; i++) {
console.log(arrayObjects[i]);
for(key in arrayObjects[i]) {
if (key == "status" && arrayObjects[i][key] == "good") {
console.log(key + "->" + arrayObjects[i][key]);
}else{
console.log("nothing found");
}
}
}