Jak uzyskać dostęp do właściwości obiektu javascript, jeśli nie znam nazw?


124

Załóżmy, że masz taki obiekt javascript:

var data = { foo: 'bar', baz: 'quux' };

Dostęp do właściwości można uzyskać poprzez nazwę właściwości:

var foo = data.foo;
var baz = data["baz"];

Ale czy można uzyskać te wartości, jeśli nie znasz nazwy właściwości? Czy nieuporządkowany charakter tych właściwości uniemożliwia ich odróżnienie?

W moim przypadku myślę konkretnie o sytuacji, w której funkcja musi zaakceptować serię par nazwa-wartość, ale nazwy właściwości mogą się zmienić.

Moje przemyślenia na temat tego, jak to zrobić do tej pory, to przekazanie nazw właściwości do funkcji wraz z danymi, ale wydaje się, że to hack. Wolałbym to zrobić z introspekcją, jeśli to możliwe.

Odpowiedzi:


144

Możesz zapętlić klucze w ten sposób:

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

To rejestruje „Nazwę” i „Wartość”.

Jeśli masz bardziej złożony typ obiektu (nie tylko zwykły obiekt podobny do skrótu, jak w oryginalnym pytaniu), będziesz chciał przechodzić tylko przez klucze, które należą do samego obiektu, w przeciwieństwie do kluczy w prototypie obiektu :

for (var key in data) {
  if (data.hasOwnProperty(key)) {
    console.log(key);
  }
}

Jak zauważyłeś, nie ma gwarancji, że klucze będą w określonej kolejności. Zwróć uwagę, jak to się różni od następujących:

for each (var value in data) {
  console.log(value);
}

Ten przykład zawiera pętle przez wartości, więc będzie rejestrować Property Namei 0. NB: Thefor each składnia jest obsługiwana głównie tylko w przeglądarce Firefox, ale nie w innych przeglądarkach.

Jeśli docelowe przeglądarki obsługują ES5 lub witryna zawiera es5-shim.js(zalecane), możesz również użyć Object.keys:

var data = { Name: 'Property Name', Value: '0' };
console.log(Object.keys(data)); // => ["Name", "Value"]

i pętla z Array.prototype.forEach:

Object.keys(data).forEach(function (key) {
  console.log(data[key]);
});
// => Logs "Property Name", 0

Czy właśnie zrobiłeś to ostatnie i naprawdę uszło ci to na sucho? Dobra robota ... =)
nickl-

To istnieje w Firefoksie ( dokumentacja ), ale uczciwa uwaga, że ​​nie jest uniwersalne. Zaktualizuję odpowiedź, aby o tym wspomnieć.
Ron DeVera

28
btw alert to zły sposób na debugowanie rzeczy, spróbuj console.log
StackOverflowed

To była najlepsza odpowiedź, gdy zadano pytanie, ale usuwam znacznik wyboru, ponieważ późniejsze wersje JS zapewniały lepsze narzędzia.
Adam Lassek

65

Stare wersje JavaScript (<ES5) wymagają użycia for..inpętli:

for (var key in data) {
  if (data.hasOwnProperty(key)) {
    // do something with key
  }
}

ES5 wprowadza Object.keys i Array # forEach, co sprawia, że ​​jest to trochę łatwiejsze:

var data = { foo: 'bar', baz: 'quux' };

Object.keys(data); // ['foo', 'baz']
Object.keys(data).map(function(key){ return data[key] }) // ['bar', 'quux']
Object.keys(data).forEach(function (key) {
  // do something with data[key]
});

ES2017 wprowadza Object.valuesi Object.entries.

Object.values(data) // ['bar', 'quux']
Object.entries(data) // [['foo', 'bar'], ['baz', 'quux']]

1
To właściwie odpowiada na pytanie, dobra robota @Adam Lassek, bardzo ładnie zrobiona.
nickl-

Używanie zarówno „nazwy”, jak i „wartości” jako kluczy obiektów jest mylące. Ta funkcja zwraca tylko klucze z listy, a nie wartości. {nazwa1: 'wartość1', nazwa2: 'wartość2'} pozwoli uniknąć nieporozumień dla początkujących. Object.keys (dane); // ['name1', 'name2']
James Nicholson

2
@JamesNicholson Zgadzam się, zredagowane tak, aby było mniej zagmatwane.
Adam Lassek,


4

Często będziesz chciał zbadać określone właściwości wystąpienia obiektu bez wszystkich jego współdzielonych metod i właściwości prototypowych:

 Obj.prototype.toString= function(){
        var A= [];
        for(var p in this){
            if(this.hasOwnProperty(p)){
                A[A.length]= p+'='+this[p];
            }
        }

    return A.join(', ');
}

3
function getDetailedObject(inputObject) {
    var detailedObject = {}, properties;

    do {
        properties = Object.getOwnPropertyNames( inputObject );
        for (var o in properties) {
            detailedObject[properties[o]] = inputObject[properties[o]];
        }
    } while ( inputObject = Object.getPrototypeOf( inputObject ) );

    return detailedObject;
}

Spowoduje to pobranie wszystkich właściwości i ich wartości (odziedziczone lub własne, wyliczalne lub nie) w nowym obiekcie. oryginalny obiekt jest nietknięty. Teraz można przejść przez nowy obiekt za pomocą

var obj = { 'b': '4' }; //example object
var detailedObject = getDetailedObject(obj);
for(var o in detailedObject) {
    console.log('key: ' + o + '   value: ' + detailedObject[o]);
}

1
var obj = {
 a: [1, 3, 4],
 b: 2,
 c: ['hi', 'there']
 }
for(let r in obj){  //for in loop iterates all properties in an object
 console.log(r) ;  //print all properties in sequence
 console.log(obj[r]);//print all properties values
}

tam, gdzie ta odpowiedź zawiera wymagania dotyczące PO, ale mały opis tego, co robisz i dlaczego OP powinien jej używać, byłby miły, nie zapomnij również, .hasOwnProperty()gdy używasz for in do iteracji obiektu.
Muhammad Omer Aslam

Dzięki, zgadzam się, że .hasOwnProperty () iteruje obiekt, ale iteruje, aby sprawdzić warunek, jednak używając go, nie możemy wydrukować wszystkich właściwości obiektu. Popraw mnie, jeśli się mylę.
Mayank_VK

Że hasOwnProperty()metoda zwraca booleanwskazuje, czy obiekt ma określona właściwość jako swoją własność (w przeciwieństwie do dziedziczenia go) . zobacz ten przykład
Muhammad Omer Aslam

1

Możesz użyć Object.keys () , "który zwraca tablicę własnych wyliczalnych nazw właściwości danego obiektu, w tej samej kolejności, w jakiej otrzymujemy w normalnej pętli."

Możesz użyć dowolnego przedmiotu zamiast stats:

var stats = {
  a: 3,
  b: 6,
  d: 7,
  erijgolekngo: 35
}
/*  this is the answer here  */
for (var key in Object.keys(stats)) {
  var t = Object.keys(stats)[key];
  console.log(t + " value =: " + stats[t]);
}


Czy mógłbyś dodać więcej wyjaśnień?
Keith Pinson,

Object.keys( stats )[key]nie ma sensu, zawsze będzie undefined.
Adam Lassek

-2
var attr, object_information='';

for(attr in object){

      //Get names and values of propertys with style (name : value)
      object_information += attr + ' : ' + object[attr] + '\n'; 

   }


alert(object_information); //Show all Object

To nic nie dodaje do zaakceptowanej odpowiedzi i przedstawia informacje w możliwie najmniej użyteczny sposób. I nie uwzględnia dziedziczonych właściwości.
Adam Lassek,
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.