2009-03-23 8 views
109

Say masz JavaScript Object takiego:Jak uzyskać dostęp do właściwości obiektu javascript, jeśli nie znam nazw?

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

można uzyskać dostęp do właściwości pod nazwą własności:

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

Ale czy to możliwe, aby uzyskać te wartości, jeśli nie wiem nazwa nieruchomoś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 akceptować serię par nazwa-wartość, ale nazwy właściwości mogą się zmieniać.

Moje przemyślenia na temat tego, jak to zrobić, to przekazanie imion właściwości do funkcji wraz z danymi, ale to wygląda jak włamanie. Wolałbym robić to z introspekcją, jeśli to możliwe.

Odpowiedz

46

Stare wersje JavaScript (< ES5) wymagać użyciu for..in pętlę:

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

ES5 wprowadza Object.keys i Array#forEach który sprawia, że ​​to trochę łatwiej:

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.values i Object.entries.

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

Teraz to właściwie odpowiada na pytanie, dobrze zrobione @Adam Lassek, bardzo ładnie wykonane. –

+0

Wprowadzanie w błąd polega na użyciu zarówno "nazwy", jak i "wartości" jako kluczy obiektów. Ta funkcja zwraca tylko klucze na liście, a nie wartości. {nazwa1: "wartość1", nazwa2: "wartość2"} pozwoli uniknąć zamieszania u początkujących. Object.keys (dane); // ['name1', 'name2'] –

+2

@JamesNicholson Zgadzam się, zredagowałem, żeby było mniej zagmatwane. –

10
for(var property in data) { 
    alert(property); 
} 
127

Można pętli kluczy tak:

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

ten rejestruje "Nazwa" oraz "wartość".

Jeśli masz bardziej złożony typ obiektu (nie tylko zwykły obiekt typu hash-like, jak w oryginalnym pytaniu), będziesz chciał tylko przechodzić przez klawisze, które należą do samego obiektu, w przeciwieństwie do klawiszy obiektu prototype:

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

Jak można zauważyć, klucze nie są gwarancją w określonej kolejności. Zauważ, jak różni są następujące ustawienia:

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

Ten przykład pętli poprzez wartości, więc byłoby zalogować Property Name i 0. N.B .: Składnia for each jest w większości obsługiwana tylko w przeglądarce Firefox, ale nie w innych przeglądarkach.

Jeśli przeglądarek docelowe wsparcia ES5 lub witryna zawiera es5-shim.js (zalecane), można również użyć Object.keys:

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

i pętlę z Array.prototype.forEach:

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

Czy udało ci się zrobić to ostatnie i faktycznie mu się udało? Dobra robota ... =) –

+0

To istnieje w Firefoksie ([docs] (https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Statements/for_each...in)), ale punkt że to nie jest uniwersalne. Zaktualizuję odpowiedź, aby o tym wspomnieć. –

+25

btw alert to zły sposób debugowania rzeczy, spróbuj konsole.log – StackOverflowed

4

Często będzie chciał zbadać właściwości obiektu ,, bez wszystkich jego wspólnych prototypowych metod i właściwości:

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

    return A.join(', '); 
} 
0
var fs = require("fs"); 

fs.stat(process.argv[1], function(err, stats){ 
if (err) { 
    console.log(err.message); 
    return;  
} else { 
console.log(JSON.stringify(stats)); 

/* this is the answer here */ 

    for (var key in Object.keys(stats)){ 
    var t = Object.keys(stats)[key]; 
    console.log(t + " value =: " + stats[t] ); 
    } 

/* to here, run in node */ 
    } 
}); 
+0

Czy możesz dodać więcej wyjaśnień? –

+0

'Object.keys (stats) [key]' nie ma sensu, zawsze będzie 'niezdefiniowane'. –

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

Nie dodaje to nic do zaakceptowanej odpowiedzi i przedstawia informacje w najmniej przydatny sposób. I nie uwzględnia odziedziczonych właściwości. –

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

Pozwoli to uzyskać wszystkie właściwości i ich wartości (odziedziczone lub rękę, przeliczalny lub nie) w nowym obiekcie. oryginalny obiekt jest nietknięty. Teraz można przesuwać 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]); 
} 
Powiązane problemy