Jeśli istnieje obiekt JavaScript:
var objects={...};
Załóżmy, że ma ponad 50 właściwości bez znajomości nazw właściwości (to znaczy bez znajomości „kluczy”), jak uzyskać każdą wartość właściwości w pętli?
Jeśli istnieje obiekt JavaScript:
var objects={...};
Załóżmy, że ma ponad 50 właściwości bez znajomości nazw właściwości (to znaczy bez znajomości „kluczy”), jak uzyskać każdą wartość właściwości w pętli?
Odpowiedzi:
Korzystając z prostej for..in
pętli:
for(var key in objects) {
var value = objects[key];
}
enumerable
flaga ma wartość false. Oznacza to między innymi, że nie będziesz iterować po metodach klas, ale będziesz iterował po metodach stworzonych w inny sposób.
W zależności od obsługiwanych przeglądarek można to zrobić na wiele sposobów. Przytłaczająca większość przeglądarek w środowisku naturalnym obsługuje ECMAScript 5 (ES5), ale należy pamiętać, że korzysta z wielu poniższych przykładów Object.keys
, które nie są dostępne w IE <9. Zobacz tabelę zgodności .
Jeśli musisz obsługiwać starsze wersje IE, jest to opcja dla Ciebie:
for (var key in obj) {
if (Object.prototype.hasOwnProperty.call(obj, key)) {
var val = obj[key];
// use val
}
}
Zagnieżdżone if
zapewnia, że nie wyliczysz właściwości w łańcuchu prototypów obiektu (takiego zachowania, którego prawie na pewno chcesz). Musisz użyć
Object.prototype.hasOwnProperty.call(obj, key) // ok
zamiast
obj.hasOwnProperty(key) // bad
ponieważ ECMAScript 5+ pozwala tworzyć obiekty bez prototypów Object.create(null)
, a te obiekty nie będą miały tej hasOwnProperty
metody. Niegrzeczny kod może również wytwarzać obiekty, które zastępują hasOwnProperty
metodę.
Z tych metod można korzystać w dowolnej przeglądarce obsługującej ECMAScript 5 i nowsze wersje. Otrzymują one wartości z obiektu i unikają wyliczania w łańcuchu prototypów. Gdzie obj
jest twój obiekt:
var keys = Object.keys(obj);
for (var i = 0; i < keys.length; i++) {
var val = obj[keys[i]];
// use val
}
Jeśli chcesz czegoś bardziej zwartego lub chcesz być ostrożnym z funkcjami w pętlach, Array.prototype.forEach
to twój przyjaciel:
Object.keys(obj).forEach(function (key) {
var val = obj[key];
// use val
});
Następna metoda buduje tablicę zawierającą wartości obiektu. Jest to wygodne do zapętlania.
var vals = Object.keys(obj).map(function (key) {
return obj[key];
});
// use vals array
Jeśli chcesz, aby osoby używające były Object.keys
bezpieczne null
(tak jak for-in
jest), możesz to zrobić Object.keys(obj || {})...
.
Object.keys
zwraca właściwości wyliczalne . Zazwyczaj wystarcza to do iteracji prostych obiektów. Jeśli masz coś z niewymiennymi właściwościami, z którymi musisz pracować, możesz użyć Object.getOwnPropertyNames
zamiastObject.keys
.
ECMAScript 2015 ułatwia iterację tablic. Możesz to wykorzystać na swoją korzyść, pracując z wartościami jeden po drugim w pętli:
for (const key of Object.keys(obj)) {
const val = obj[key];
// use val
}
Korzystając z funkcji strzałek tłuszczu w ECMAScript 2015, mapowanie obiektu na tablicę wartości staje się jednowierszowe:
const vals = Object.keys(obj).map(key => obj[key]);
// use vals array
ECMAScript 2015 wprowadza Symbol
, których instancje mogą być używane jako nazwy właściwości. Aby uzyskać symbole obiektu do wyliczenia, użyj Object.getOwnPropertySymbols
(ta funkcja powoduje, że Symbol
nie można jej używać do tworzenia właściwości prywatnych). Nowy Reflect
interfejs API od ECMAScript 2015 zapewnia Reflect.ownKeys
, która zwraca listę nazw właściwości (w tym również tych, których nie można wyliczyć) i symboli.
Wyjaśnienia tablic zostały usunięte z ECMAScript 6 przed publikacją. Przed ich usunięciem rozwiązanie wyglądałoby następująco:
const vals = [for (key of Object.keys(obj)) obj[key]];
// use vals array
ECMAScript 2016 dodaje funkcje, które nie wpływają na ten temat. Dodano specyfikację ECMAScript 2017 Object.values
i Object.entries
. Obie zwracają tablice (co będzie zaskakujące dla niektórych, biorąc pod uwagę analogię z Array.entries
). Object.values
może być używany tak jak jest lub z for-of
pętlą.
const values = Object.values(obj);
// use values array or:
for (const val of Object.values(obj)) {
// use val
}
Jeśli chcesz użyć zarówno klucza, jak i wartości, to Object.entries
jest dla Ciebie. Tworzy tablicę wypełnioną [key, value]
parami. Możesz użyć tego w obecnej postaci lub (zwróć również uwagę na przypisanie do restrukturyzacji ECMAScript 2015) w for-of
pętli:
for (const [key, val] of Object.entries(obj)) {
// use key and val
}
Object.values
PodkładkaWreszcie, jak zauważono w komentarzach i teh_senaus w innej odpowiedzi, warto użyć jednego z nich jako podkładki. Nie martw się, poniższe nie zmieniają prototypu, po prostu dodaje metodę Object
(co jest znacznie mniej niebezpieczne). Za pomocą funkcji strzałek grubych można to zrobić również w jednym wierszu:
Object.values = obj => Object.keys(obj).map(key => obj[key]);
którego możesz teraz używać
// ['one', 'two', 'three']
var values = Object.values({ a: 'one', b: 'two', c: 'three' });
Jeśli chcesz uniknąć przyciemniania, gdy Object.values
istnieje natywny , możesz:
Object.values = Object.values || (obj => Object.keys(obj).map(key => obj[key]));
Pamiętaj o przeglądarkach / wersjach, które musisz obsługiwać. Powyższe informacje są poprawne tam, gdzie metody lub funkcje językowe są zaimplementowane. Na przykład obsługa ECMAScript 2015 była do niedawna domyślnie wyłączona w wersji V8, która zasilała przeglądarki takie jak Chrome. Należy unikać funkcji z ECMAScript 2015, dopóki przeglądarki, które mają obsługiwać, nie implementują potrzebnych funkcji. Jeśli użyjesz Babel do skompilowania kodu do ECMAScript 5, masz dostęp do wszystkich funkcji tej odpowiedzi.
obj
dwa razy wspomnieć . Wydaje mi się, że utworzenie funkcji pomocnika jest nieuniknione? Coś jak wartości (obj).
Object.values = obj => Object.keys(obj).map(key => obj[key]);
Oto funkcja wielokrotnego użytku do wprowadzania wartości do tablicy. Uwzględnia również prototypy.
Object.values = function (obj) {
var vals = [];
for( var key in obj ) {
if ( obj.hasOwnProperty(key) ) {
vals.push(obj[key]);
}
}
return vals;
}
Object
nie stanowi większego problemu ( Object.keys
jest częstym oszustwem), prawdopodobnie myślisz o modyfikacji prototypu Object.
hasOwnProperty()
? Jak iteracja klucza w pętli tego obiektu nie ma właściwości?
Jeśli masz dostęp do Underscore.js, możesz użyć następującej _.values
funkcji:
_.values({one : 1, two : 2, three : 3}); // return [1, 2, 3]
Jeśli naprawdę chcesz tablicy Wartości, uważam, że jest to czystsze niż budowanie tablicy za pomocą pętli for ... in.
ECMA 5.1+
function values(o) { return Object.keys(o).map(function(k){return o[k]}) }
Warto zauważyć, że w większości przypadków tak naprawdę nie potrzebujesz tablicy wartości, szybciej to zrobisz:
for(var k in o) something(o[k]);
Powtarza się to nad kluczami obiektu o. W każdej iteracji k jest ustawione na klucz o.
ES5 Object.keys
var a = { a: 1, b: 2, c: 3 };
Object.keys(a).map(function(key){ return a[key] });
// result: [1,2,3]
użyj polifillu, takiego jak:
if(!Object.values){Object.values=obj=>Object.keys(obj).map(key=>obj[key])}
następnie użyj
Object.values(my_object)
3) zysk!
ECMA2017 i następne:
Object.values(obj)
pobierze wszystkie wartości właściwości w postaci tablicy.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_objects/Object/values
Najwyraźniej - jak niedawno się dowiedziałem - jest to najszybszy sposób na zrobienie tego:
var objs = {...};
var objKeys = Object.keys(obj);
for (var i = 0, objLen = objKeys.length; i < objLen; i++) {
// do whatever in here
var obj = objs[objKeys[i]];
}
Pytanie nie określa, czy chce się dziedziczyć i właściwości, których nie można wyliczyć.
Jest pytanie o uzyskanie wszystkiego, odziedziczone właściwości i właściwości niepoliczalne , których Google nie może łatwo znaleźć.
Moim rozwiązaniem jest:
function getAllPropertyNames(obj) {
let result = new Set();
while (obj) {
Object.getOwnPropertyNames(obj).forEach(p => result.add(p));
obj = Object.getPrototypeOf(obj);
}
return [...result];
}
A następnie iteruj nad nimi, po prostu użyj pętli for-of:
Użyj: Object.values()
przekazujemy obiekt jako argument i otrzymujemy tablicę wartości jako wartość zwracaną.
Zwraca tablicę wartości danego obiektu, które można wyliczyć. Otrzymasz te same wartości, co przy użyciu for in
pętli, ale bez właściwości Prototypu. Ten przykład prawdopodobnie wyjaśni wszystko:
function person (name) {
this.name = name;
}
person.prototype.age = 5;
let dude = new person('dude');
for(let prop in dude) {
console.log(dude[prop]); // for in still shows age because this is on the prototype
} // we can use hasOwnProperty but this is not very elegant
// ES6 +
console.log(Object.values(dude));
// very concise and we don't show props on prototype
Oto funkcja podobna do PHP array_values ()
function array_values(input) {
var output = [], key = '';
for ( key in input ) { output[output.length] = input[key]; }
return output;
}
Oto jak uzyskać wartości obiektu, jeśli używasz ES6 lub wyższej:
Array.from(values(obj));
Ponieważ Object.values(<object>)
zostanie wbudowany w ES7 i
Do czasu oczekiwania na wsparcie wszystkich przeglądarek możesz umieścić go w funkcji:
Object.vals=(o)=>(Object.values)?Object.values(o):Object.keys(o).map((k)=>o[k])
Następnie :
Object.vals({lastname:'T',firstname:'A'})
// ['T','A']
Object.entries robią to w lepszy sposób.
var dataObject = {"a":{"title":"shop"}, "b":{"title":"home"}}
Object.entries(dataObject).map(itemArray => {
console.log("key=", itemArray[0], "value=", itemArray[1])
})
const myObj = { a:1, b:2, c:3 }
Uzyskaj wszystkie wartości:
najkrótsza droga:
const myValues = Object.values(myObj)
const myValues = Object.keys(myObj).map(key => myObj[key])
w użyciu ECMAScript5
keys = Object.keys(object);
W przeciwnym razie, jeśli Twoja przeglądarka go nie obsługuje, użyj dobrze znanego for..in loop
for (key in object) {
// your code here
}
object[key]
do uzyskania wartości w pętli.
for..in
(i hasOwnProperty), więc tak naprawdę nic nie zyskuje. Chciałbym, żeby ECMAScript 5 zdefiniował Object.pairs
(i Object.items
dla [[key, value], ..]
), ale niestety, nie ma.
Teraz używam Dojo Toolkit, ponieważ starsze przeglądarki nie obsługują Object.values
.
require(['dojox/lang/functional/object'], function(Object) {
var obj = { key1: '1', key2: '2', key3: '3' };
var values = Object.values(obj);
console.log(values);
});
Wynik :
['1', '2', '3']