Mam obiekt JavaScript, taki jak:

var p = {
    "p1": "value1",
    "p2": "value2",
    "p3": "value3"
};

Teraz chcę pętli przez elementy p (p1, p2, p3 ...) i zdobądź ich klucze i wartości. Jak mogę to zrobić?

W razie potrzeby mogę modyfikować obiekt JavaScript. Moim ostatecznym celem jest pętlę przez kilka par wartości kluczowych i jeśli to możliwe, chcę uniknąć używania eval.

3240
Tanmoy 26 marzec 2009, 09:01

27 odpowiedzi

Najlepsza odpowiedź

Możesz użyć for-in pętla, jak pokazano przez innych. Musisz jednak również upewnić się, że otrzymasz klucz, jest rzeczywista właściwość obiektu i nie pochodzi z prototypu.

Oto fragment:

var p = {
    "p1": "value1",
    "p2": "value2",
    "p3": "value3"
};

for (var key in p) {
    if (p.hasOwnProperty(key)) {
        console.log(key + " -> " + p[key]);
    }
}

dla z obiektów.keys () Alternatywa:

var p = {
    0: "value1",
    "b": "value2",
    key: "value3"
};

for (var key of Object.keys(p)) {
    console.log(key + " -> " + p[key])
}

Zwróć uwagę na użycie for-of zamiast {{x1 }}, jeśli nie jest używany, powróci niezdefiniowany na wymienionych właściwościach, a Object.keys() zapewnia zastosowanie tylko właściwości własnych obiektów bez całego właściwości łańcucha prototypowego

Korzystanie z nowej Object.entries() Metoda:

Uwaga: Ta metoda nie jest natywnie obsługiwana przez program Internet Explorer. Możesz rozważyć użycie polikflistów dla starszych przeglądarek.

const p = {
    "p1": "value1",
    "p2": "value2",
    "p3": "value3"
};

for (let [key, value] of Object.entries(p)) {
  console.log(`${key}: ${value}`);
}
4609
KostasX 24 luty 2020, 05:32

Ponieważ ES06 można uzyskać wartości obiektu jako tablicę

let arrValues = Object.values( yourObject) ;

Zwraca tablicę wartości obiektu i nie wyodrębnia wartości z prototypu !!

MDN DOCS Obiekt.Values ()

I dla kluczy (już odpowiedziałeś przede mną)

let arrKeys   = Object.keys(yourObject);
4
yehonatan yehezkel 22 sierpień 2018, 15:41

Object.entries() Funkcja:

var p = {
	    "p1": "value1",
	    "p2": "value2",
	    "p3": "value3"
	};

for (var i in Object.entries(p)){
	var key = Object.entries(p)[i][0];
	var value = Object.entries(p)[i][1];
	console.log('key['+i+']='+key+' '+'value['+i+']='+value);
}
3
nrb 29 październik 2018, 19:21

Pod ECMASCRIPT 5, można połączyć {{x0} } i Array.prototype.forEach():

var obj = { first: "John", last: "Doe" };

Object.keys(obj).forEach(function(key) {
    console.log(key, obj[key]);
});

ECMAMAScript 6 dodaje for...of :

for (const key of Object.keys(obj)) {
    console.log(key, obj[key]);
}

ECMAScript 8 dodaje Object.entries() , co pozwala uniknąć poszukiwania każdej wartości w oryginalnym obiekcie:

Object.entries(obj).forEach(
    ([key, value]) => console.log(key, value)
);

Możesz łączyć for...of, destrucuring i {x1}}:

for (const [key, value] of Object.entries(obj)) {
    console.log(key, value);
}

Oba Object.keys() i Object.entries() Itera Itera Właściwości w tej samej kolejności, co for...in Loop , ale ignoruj łańcuch prototypowy . Tylko własne obiekty właściwości są iterowane.

1176
T.J. Crowder 15 maj 2019, 17:17

Musisz użyć pętli w pętli

Ale bądź bardzo ostrożny przy użyciu tego rodzaju pętli, ponieważ jest to pętla wszystkich właściwości wzdłuż łańcucha prototypu .

Dlatego, gdy używając pętli w pętlach, zawsze używaj metody hasOwnProperty, aby określić, czy aktualna właściwość w iteracji jest naprawdę właściwością obiektu, na którym sprawdzasz:

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
}
351
Vitim.us 24 luty 2016, 10:51

W ECMAScript 5 masz nowe podejście na polach iteracji literal - {x0}}

Więcej informacji można zobaczyć na MDN

Mój wybór jest poniżej szybszym rozwiązaniem w obecnych wersjach przeglądarek (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;
}

Możesz porównać wydajność tego podejścia z różnymi wdrożeniami na jsperf.com:

Obsługa przeglądarki Możesz zobaczyć na Tabela kompat KANGOX

Dla starej przeglądarki masz proste i Full Polifill

UPD:

Porównanie wydajności dla wszystkich najpopularniejszych przypadków w tym pytaniu na perfjs.info:

Obiekt literał iteracja

54
Pencroff 12 wrzesień 2016, 22:11

Możesz po prostu iterować go jak:

for (var key in p) {
  alert(p[key]);
}

Należy pamiętać, że key nie będzie podjąć wartości nieruchomości, to tylko wartość indeksu.

53
billynoah 9 październik 2018, 15:11

Ponieważ ES2015 staje się coraz bardziej popularny, opublikuję tę odpowiedź, która obejmuje użycie generatora i iteratora, aby płynnie iterować pary [key, value]. Ponieważ jest to możliwe w innych językach na przykład ruby.

OK tutaj jest kod:

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}`);
}

Wszystkie informacje o tym, jak możesz wykonać iterator i generator, które można znaleźć na stronie Developer Mozilla.

Mam nadzieję, że komuś pomogło.

EDYTUJ:

ES2017 obejmie Object.entries, która ułatwią ITeresting nad [key, value] w obiektach jeszcze łatwiejsze. Wiadomo teraz, że będzie to część standardu zgodnie z TS39 Informacje o scenie.

Myślę, że nadszedł czas, aby zaktualizować moją odpowiedź, aby pozwolić mu jeszcze bardziej świeżym niż teraz.

const MyObject = {
  'a': 'Hello',
  'b': 'it\'s',
  'c': 'me',
  'd': 'you',
  'e': 'looking',
  'f': 'for',
};

for (const [k, v] of Object.entries(MyObject)) {
  console.log(`Here is key ${k} and here is value ${v}`);
}

Więcej informacji na temat użycia MDN strona

28
Ran Marciano 1 luty 2021, 08:59
for(key in p) {
  alert( p[key] );
}

UWAGA: Możesz to zrobić nad tablicami, ale będziesz iterować ponad length i inne właściwości.

27
Kristian 3 listopad 2012, 21:46

Po obejrzeniu wszystkich odpowiedzi tutaj Hasownproperty nie jest wymagane na moje własne użycie, ponieważ mój obiekt JSON jest czysty; Naprawdę nie ma sensu w dodaniu dodatkowego przetwarzania JavaScript. To wszystko, czego używam:

for (var key in p) {
    console.log(key + ' => ' + p[key]);
    // key is key
    // value is p[key]
}
21
Francis Lewis 18 sierpień 2011, 20:50

Przez prototyp z foreach () , który powinien pominąć łańcuch prototypowy właściwości:

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
20
strider 9 grudzień 2012, 05:05
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>
14
TessavWalstijn 19 marzec 2018, 14:08

Możesz także użyć obiektów.keys () i itera na klucze obiektu jak poniżej, aby uzyskać wartość:

var p = {
    "p1": "value1",
    "p2": "value2",
    "p3": "value3"
};

Object.keys(p).forEach((key)=> {
 console.log(key +' -> '+ p[key]);
});
14
Onera 13 sierpień 2019, 07:14

Obiekt.keys (obj): tablica

Pobiera wszystkie klasyfikowane klawisze łańcuchowe wszystkich wymienionych własnych (nie dziedziczonych) właściwości.

Daje więc taką samą listę kluczy, jak zamierzasz przetestować każdy klawisz obiektu z HasownProperty. Nie potrzebujesz dodatkowej operacji testowej niż Object.keys( obj ).forEach(function( key ){}) ma być szybszy. Udowodnijmy to:

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.");

W moim Firefoksie mam następujące wyniki

  • Podejście obiekt.Keys zajęło 40.21101451665163 Milisekund.
  • Za ... W / HasownProperty podejście zajęło 98.26163508463651 milisekund.

Ps. Na Chrome Różnica jeszcze większa http://codepen.io/dsheiko/pen/jdrqxa

PS2: W ES6 (ECMASCRIPT 2015) możesz iterować iterable obiekt ładniejszy:

let map = new Map().set('a', 1).set('b', 2);
for (let pair of map) {
    console.log(pair);
}

// OR 
let map = new Map([
    [false, 'no'],
    [true,  'yes'],
]);
map.forEach((value, key) => {
    console.log(key, value);
});
13
Dmitry Sheiko 22 czerwiec 2015, 11:33

W najnowszym skrypcie ES możesz zrobić coś takiego:

Object.entries(p);
11
Flimm 6 maj 2020, 11:07

Tylko kod JavaScript bez zależności:

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
}
10
Peter Mortensen 16 czerwiec 2016, 17:34

Oto kolejna metoda do iteracji przez obiekt.

   var p = {
"p1": "value1",
"p2": "value2",
"p3": "value3"
};


Object.keys(p).forEach(key => { console.log(key, p[key]) })
10
Harsh Patel 20 grudzień 2017, 04:42

Metoda Object.keys() zwraca tablicę danego obiektu własnych właściwości. Przeczytaj więcej o tym Oto

var p = {
    "p1": "value1",
    "p2": "value2",
    "p3": "value3"
};

Object.keys(p).map((key)=> console.log(key + "->" + p[key]))
8
Muhammad Usman 16 listopad 2017, 21:22

Możesz dodać proste funkcję foreach do wszystkich obiektów, dzięki czemu można automatycznie pętli przez dowolny obiekt:

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
});

Dla tych ludzi, którzy nie lubią " dla ... w " - Metoda:

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
});

Teraz możesz proste połączenie:

p.forEach (function(key, value){
    console.log ("Key: " + key);
    console.log ("Value: " + value);
});

Jeśli nie chcesz uzyskać konfliktów z innymi metodami Foreach, możesz nazwać go wyjątkową nazwą.

7
Biber 28 listopad 2016, 08:25

przy użyciu for-of na Object.keys()

Lubić:

let object = {
   "key1": "value1"
   "key2": "value2"
   "key3": "value3"
};

for (var key of Object.keys(p)) {
   console.log(key + " : " + object[key])
}
7
Ran Marciano 1 luty 2021, 09:24

Pętle mogą być całkiem interesujące przy użyciu czystego JavaScript. Wydaje się, że tylko specyfikacja ECMA6 (nowa specyfikacja JavaScript 2015) dostała pętle pod kontrolą. Niestety, gdy piszę to, zarówno przeglądarki, jak i popularne zintegrowane środowisko rozwoju (IDE) wciąż walczą o pełni obsługę nowych dzwonów i gwizdków.

Przy spojrzeniu wygląda tak, jak wygląda pętla obiekt JavaScript przed 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;
  }
}

Wiem, że jest to poza zakresem z tym pytaniem, ale w 2011 r. ECMAScript 5.1 Dodano metodę forEach dla macierzy tylko, które zasadniczo tworzył nowy lepszy sposób na pętlę przez tablice, wciąż pozostawiając nieważne obiekty ze starym gadatym i mylące for pętla. Ale dziwną częścią jest to, że ta nowa metoda {x2}} nie obsługuje break, która doprowadziła do wszelkiego rodzaju innych problemów.

Zasadniczo w 2011 r. Nie ma prawdziwego solidnego sposobu pętli w JavaScript inne niż wiele popularnych bibliotek (jQuery, podkreśla itp.) Postanowił ponownie wdrożyć.

Od 2015 r. Teraz mamy lepsze wyjście ze sposobu na pętlę (i przełamać) dowolnego typu obiektu (w tym tablice i łańcuchy). Oto, co właśnie wygląda pętla w JavaScript, gdy zalecenie staje się głównym nurtem:

for (let [key, value] of Object.entries(object)) {
    console.log(key); // This is the key;
    console.log(value); // This is the value;
}

Należy pamiętać, że większość przeglądarek nie będzie obsługiwać kodu powyżej 18 czerwca 2016 r. Nawet w Chrome musisz włączyć tę specjalną flagę, aby pracować: chrome://flags/#enable-javascript-harmony

Dopóki nie staje się nowym standardem, stara metoda może być nadal stosowana, ale istnieją również alternatywy w popularnych bibliotekach, a nawet Lekkie alternatywy dla tych, którzy nie używają żadnego z tych bibliotek.

6
Nicolas Bouvrette 18 czerwiec 2016, 12:55

W ES6 mamy znane symbole, aby odsłonić pewne wcześniej wewnętrzne metody, możesz użyć go do określenia, jak działa Iteratorzy dla tego obiektu:

var p = {
    "p1": "value1",
    "p2": "value2",
    "p3": "value3",
    *[Symbol.iterator]() {
        yield *Object.keys(this);
    }
};

[...p] //["p1", "p2", "p3"]

Daje to ten sam wynik jako użycie do ... w pętli ES6.

for(var key in p) {
    console.log(key);
}

Ale ważne jest, aby poznać możliwości, które teraz masz za pomocą ES6!

5
Bamieh 20 wrzesień 2016, 09:04

Zrobiłbym to, a nie sprawdzanie obj.hasOwnerProperty w pętli for ... in.

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");
}
5
Lewis 10 listopad 2016, 10:04
    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]);
        }
    }
}
5
Zakaria Acharki 14 wrzesień 2018, 17:51

Jeśli chcesz iterować ponad nie Niezliczeni właściwości , jak również można użyć Object.getOwnPropertyNames(obj), aby zwrócić tablicę wszystkich właściwości (niezliczone lub nie) znalezione bezpośrednio na danym obiekcie.

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/>');
});
4
Dheeraj Vepakomma 11 listopad 2015, 05:26

Jeśli ktoś musi pętli przez arrayobjects ze stanem :

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");
      }
   }
}
4
Tadas V. 22 lipiec 2016, 03:48

Biorąc pod uwagę ES6 Chciałbym dodać własną łyżkę cukru i zapewnić jeszcze jedno podejście do zachowywania właściwości obiektu.

Od zwykłego JS Obiekt nie jest iterable właśnie z pudełka, Nie jesteśmy w stanie użyć pętli for..of, aby iterować o swojej zawartości. Ale nikt nie może powstrzymać nas , aby utrudnił to iterable .

Mamy obiekt book.

let book = {
  title: "Amazing book",
  author: "Me",
  pages: 3
}

book[Symbol.iterator] = function(){

  let properties = Object.keys(this); // returns an array with property names
  let counter = 0;
  let isDone = false;

  let next = () => {
    if(counter >= properties.length){
      isDone = true;
    }
    return { done: isDone, value: this[properties[counter++]] }
  }

  return { next };
}

Ponieważ uczyniliśmy to, możemy go użyć w ten sposób:

for(let pValue of book){
  console.log(pValue);
}
------------------------
Amazing book
Me
3

Lub jeśli znasz moc ES6 generatory, Więc na pewno możesz dokonać kodu powyżej znacznie krótszego.

book[Symbol.iterator] = function *(){

  let properties = Object.keys(this);
  for (let p of properties){
    yield this[p];
  }

}

Jasne, możesz zastosować takie zachowanie dla wszystkich obiektów z tworzeniem {x0}} iterable na poziomie prototype.

Object.prototype[Symbol.iterator] = function() {...}

Również obiekty, które są zgodne z iterable protokołem mogą być używane z nowym funkcją ES2015 Spread operator zatem możemy odczytać wartości właściwości obiektu jako tablicę.

let pValues = [...book];
console.log(pValues);
-------------------------
["Amazing book", "Me", 3]

Albo możesz użyć Destrucructing Przypisanie:

let [title, , pages] = book; // notice that we can just skip unnecessary values
console.log(title);
console.log(pages);
------------------
Amazing book
3

Możesz sprawdzić jsfiddle ze wszystkimi kodami, które podane powyżej.

4
Artyom Pranovich 2 wrzesień 2016, 13:56