Jak uzyskać wszystkie wartości właściwości obiektu JavaScript (bez znajomości kluczy)?


455

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?


23
Uwaga dla czytelników: nie przegap bardzo wnikliwej drugiej odpowiedzi
Pandaiolo

Odpowiedzi:


447

Korzystając z prostej for..inpętli:

for(var key in objects) {
    var value = objects[key];
}

90
Uważaj na dziedziczone właściwości prototypowego obiektu. Patrz: hasOwnProperty ()
oliwkowy

102
Jeśli czytasz tę odpowiedź, zdecydowanie powinieneś przeczytać drugą
mgarciaisaia

18
Jeśli czytasz tę odpowiedź i być może masz do czynienia z łańcuchami, zdecydowanie powinieneś uderzyć javascript w twarz.

Jeśli czytasz powyższą odpowiedź i chcesz uderzyć JavaScript w twarz, spróbuj lodash
slugmandrew

Powinien prawdopodobnie zaznaczyć, że NIE będzie to obejmowało właściwości, dla których ich enumerableflaga 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.
rich remer

1012

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 .

ECMAScript 3+

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 ifzapewnia, ż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 hasOwnPropertymetody. Niegrzeczny kod może również wytwarzać obiekty, które zastępują hasOwnPropertymetodę.

ECMAScript 5+

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 objjest 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.forEachto 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.keysbezpieczne null(tak jak for-injest), możesz to zrobić Object.keys(obj || {})....

Object.keyszwraca 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.getOwnPropertyNameszamiastObject.keys .

ECMAScript 2015+ (AKA ES6)

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 Reflectinterfejs 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.

Wyrażenia tablicowe (nie próbuj używać)

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 2017+

ECMAScript 2016 dodaje funkcje, które nie wpływają na ten temat. Dodano specyfikację ECMAScript 2017 Object.valuesi Object.entries. Obie zwracają tablice (co będzie zaskakujące dla niektórych, biorąc pod uwagę analogię z Array.entries). Object.valuesmoże być używany tak jak jest lub z for-ofpę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.entriesjest 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-ofpętli:

for (const [key, val] of Object.entries(obj)) {
    // use key and val
}

Object.values Podkładka

Wreszcie, 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.valuesistnieje natywny , możesz:

Object.values = Object.values || (obj => Object.keys(obj).map(key => obj[key]));

Wreszcie...

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.


9
To powinna być zaakceptowana (lub przynajmniej bardziej pozytywna) odpowiedź, ponieważ zaakceptowana jest niekompletna (@olive to zaznacza).
0xc0de,

Szkoda, że ​​ze wszystkich tak zwanych sztuczek musimy jeszcze objdwa razy wspomnieć . Wydaje mi się, że utworzenie funkcji pomocnika jest nieuniknione? Coś jak wartości (obj).
Steven Haryanto

Każda z tych metod może być stosowana jako podkładka dystansowa. Na przykład:Object.values = obj => Object.keys(obj).map(key => obj[key]);
qubyte

1
Rozwiązania ECMA 5 powinny działać we wszystkich nowoczesnych przeglądarkach. ECMA 6 nie został jeszcze sfinalizowany, a wsparcie jest wstępne we wszystkich przeglądarkach. W Chrome ECMA 6 jest częściowo zaimplementowany, ale wyłączony. W przeglądarce Firefox obsługa jest lepsza, ale interpretacja tablic jest nieprawidłowa (jak wspomniano). Myślałem, że moje użycie czasu przyszłego implikuje to. @JacekLampart, które rozwiązanie dało ci błąd?
qubyte

2
Nie mogę sobie wyobrazić, dlaczego musimy czekać na ES2017, aby uzyskać metodę Object.values ​​().
Herbertusz

31

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

15
Modyfikacja Objectnie stanowi większego problemu ( Object.keysjest częstym oszustwem), prawdopodobnie myślisz o modyfikacji prototypu Object.
sandstrom

Dlaczego miałbyś chcieć testować hasOwnProperty()? Jak iteracja klucza w pętli tego obiektu nie ma właściwości?
1252748,

4
Google it @ thomas, to ważne. Może mieć właściwości z łańcucha prototypów.
Joe


14

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.


9

ES5 Object.keys

var a = { a: 1, b: 2, c: 3 };
Object.keys(a).map(function(key){ return a[key] });
// result: [1,2,3]

3
Dlaczego zostało to odrzucone? Powiedziałbym, że jest to jedno z najczystszych rozwiązań.
Sebastian Hojas

Nie wiem, dlaczego jest to przegłosowane. Jest to najłatwiejsze i najczystsze rozwiązanie w js bez użycia bibliotek lub innych narzędzi.
sanjeev shetty

5

Możesz przeglądać klucze:

foo = {one:1, two:2, three:3};
for (key in foo){
    console.log("foo["+ key +"]="+ foo[key]);
}

wyświetli:

foo[one]=1
foo[two]=2
foo[three]=3

2
Musisz także zaznaczyć `hasOwnProperty () ', jeśli chcesz uniknąć odziedziczonych atrybutów.
0xc0de,

3

Dla tych, którzy wcześnie dostosowują ludzi w erze CofeeScript, oto kolejny jej odpowiednik.

val for key,val of objects

Co może być lepsze niż to, ponieważ objectsmożna zmniejszyć, aby pisać ponownie i zmniejszyć czytelność.

objects[key] for key of objects

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!



2

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

czy możesz podać codepen lub jsfiddle tego przykładu? dzięki.
Chris22

2

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:


1

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 inpę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


1
const object1 = {
  a: 'somestring',
  b: 42
};

for (let [key, value] of Object.entries(object1)) {
  console.log(`${key}: ${value}`);
}

// expected output:
// "a: somestring"
// "b: 42"
// order is not guaranteed

0

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

Z jakiegoś powodu wartości () działają w Chrome i Firefox, ale nie w iojs / node.
jaggedsoft

0

Kompatybilny z ES7, nawet niektóre przeglądarki jeszcze go nie obsługują

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']

Gdy przeglądarki staną się kompatybilne z ES7, nie będziesz musiał nic zmieniać w kodzie.


0

Zdaję sobie sprawę, że jestem trochę późno, ale tutaj jest to podkładka dla nowego firefox 47 Object.valuesmetodzie

Object.prototype.values = Object.prototype.values || function(obj) {
  return this.keys(obj).map(function(key){
    return obj[key];
  });
};

0

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


0

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])


-1
var objects={...}; this.getAllvalues = function () {
        var vls = [];
        for (var key in objects) {
            vls.push(objects[key]);
        }
        return vls;
    }

-5

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
}

17
Pytanie dotyczyło wartości, a nie kluczy.
zachelrath

@zachelrath Masz rację. - Ale ten skrypt jest przydatny, jeśli chcesz uzyskać wartości, ponieważ gdy znasz klucze, możesz użyć ich object[key]do uzyskania wartości w pętli.
fridojet

2
@fridojet Ale można to zrobić za pomocą for..in(i hasOwnProperty), więc tak naprawdę nic nie zyskuje. Chciałbym, żeby ECMAScript 5 zdefiniował Object.pairs(i Object.itemsdla [[key, value], ..]), ale niestety, nie ma.
user2246674

-8

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']

5
Ściśle mówiąc, tablica jest niepoprawna. Masz tablicę ciągów zamiast tablicy liczb.
qubyte

-10

posługiwać się

console.log(variable)

a jeśli używasz Google Chrome, otwórz konsolę, używając Ctrl + Shift + j

Idź do >> Konsoli

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.