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.