Bir JavaScript Nesnesinin tüm özellik değerlerini (anahtarları bilmeden) nasıl alabilirim?


Yanıtlar:


448

Basit bir for..indöngü kullanarak :

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

90
Devralınan prototip nesnesinin özelliklerine dikkat edin. Bakınız: hasOwnProperty ()
zeytin

102
Bu cevabı okuyorsanız, kesinlikle diğerini
mgarciaisaia

18
Bu yanıtı okuyorsanız ve muhtemelen dizelerle uğraşıyorsanız, javascript'i kesinlikle yüzünüze yumruklamanız gerekir.

Yukarıdaki cevabı okuduysanız ve JavaScript'i karşısında yumruklamak istiyorsanız, lodash'ı
slugmandrew

Muhtemelen bunun enumerablebayrağı yanlış olarak ayarlanmış özellikleri İÇERMEYECEKTİR. Bu - diğer şeylerin yanı sıra - herhangi bir sınıf yöntemi üzerinde tekrarlamayacağınız, ancak başka yollarla oluşturulan yöntemler üzerinde tekrarlayacağınız anlamına gelir.
zengin remer

1012

Hangi tarayıcıları desteklemeniz gerektiğine bağlı olarak, bu çeşitli şekillerde yapılabilir. Vahşi ortamlardaki tarayıcıların ezici çoğunluğu ECMAScript 5'i (ES5) destekler, ancak Object.keysIE <9'da bulunmayan aşağıdaki örneklerin çoğunun kullanıldığına dikkat edin. Uyumluluk tablosuna bakın .

ECMAScript 3+

IE'nin eski sürümlerini desteklemeniz gerekiyorsa, bu sizin için bir seçenektir:

for (var key in obj) {
    if (Object.prototype.hasOwnProperty.call(obj, key)) {
        var val = obj[key];
        // use val
    }
}

Yuvalanmış if, nesnenin prototip zincirindeki özellikler üzerinde numaralandırmamanızı sağlar (bu kesinlikle istediğiniz davranıştır). Kullanmalısın

Object.prototype.hasOwnProperty.call(obj, key) // ok

ziyade

obj.hasOwnProperty(key) // bad

çünkü ECMAScript 5+ ile prototipsiz nesneler oluşturmanıza izin verir Object.create(null)ve bu nesnelerin hasOwnPropertyyöntemi yoktur. Yaramaz kod, hasOwnPropertyyöntemi geçersiz kılan nesneler de üretebilir .

ECMAScript 5+

Bu yöntemleri ECMAScript 5 ve üstünü destekleyen herhangi bir tarayıcıda kullanabilirsiniz. Bunlar bir nesneden değerler alır ve prototip zinciri üzerinde numaralandırmayı önler. objNesneniz nerede :

var keys = Object.keys(obj);

for (var i = 0; i < keys.length; i++) {
    var val = obj[keys[i]];
    // use val
}

Biraz daha kompakt bir şey istiyorsanız veya döngülerdeki işlevlere dikkat etmek istiyorsanız Array.prototype.forEach, arkadaşınız:

Object.keys(obj).forEach(function (key) {
    var val = obj[key];
    // use val
});

Sonraki yöntem, bir nesnenin değerlerini içeren bir dizi oluşturur. Bu, döngü için uygundur.

var vals = Object.keys(obj).map(function (key) {
    return obj[key];
});

// use vals array

Kullananlar (olduğu gibi ) Object.keyskarşı güvenli yapmak istiyorsanız, yapabilirsiniz .nullfor-inObject.keys(obj || {})...

Object.keysnumaralandırılabilir özellikler döndürür . Basit nesneler üzerinde yineleme yapmak için bu genellikle yeterlidir. Çalışmanız gereken numaralandırılamayan özelliklere sahip bir şeyiniz varsa Object.getOwnPropertyNames, yerine kullanabilirsiniz Object.keys.

ECMAScript 2015+ (AKA ES6)

ECMAScript 2015 ile dizileri yinelemek daha kolaydır. Bir döngüde değerlerle tek tek çalışırken bu avantajı kendi yararınıza kullanabilirsiniz:

for (const key of Object.keys(obj)) {
    const val = obj[key];
    // use val
}

ECMAScript 2015 yağ oku işlevlerini kullanarak, nesneyi bir değer dizisiyle eşleştirmek tek satırlık olur:

const vals = Object.keys(obj).map(key => obj[key]);

// use vals array

ECMAScript 2015 Symbol, örnekleri mülk adları olarak kullanılabilen tanıttı . Numaralandırmak için bir nesnenin sembollerini almak için, kullanım Object.getOwnPropertySymbols(neden bu işlevi Symbol olamaz özel mülk yapmak için kullanılabilir). ReflectECMAScript 2015'teki yeni API Reflect.ownKeys, özellik adlarının (numaralandırılamayanlar da dahil olmak üzere) ve simgelerin bir listesini döndürür.

Dizi kavrayışları (kullanmaya çalışmayın)

Dizi anlaşmaları yayınlanmadan önce ECMAScript 6'dan çıkarılmıştır . Çıkarılmadan önce bir çözüm şöyle görünebilirdi:

const vals = [for (key of Object.keys(obj)) obj[key]];

// use vals array

ECMAScript 2017+

ECMAScript 2016, bu konuyu etkilemeyen özellikler ekler. ECMAScript 2017 belirtimi Object.valuesve ekler Object.entries. Her ikisi de dizileri döndürür (bazılarına benzetme ile şaşırtıcı olacaktır Array.entries). Object.valuesolduğu gibi veya bir for-ofdöngü ile kullanılabilir .

const values = Object.values(obj);

// use values array or:

for (const val of Object.values(obj)) {
    // use val
}

Hem anahtarı hem de değeri kullanmak istiyorsanız, o zaman Object.entriestam size göre. Çiftlerle dolu bir dizi üretir [key, value]. Bunu olduğu gibi kullanabilir veya bir for-ofdöngüde (ayrıca ECMAScript 2015 yıkım atamasına da dikkat edebilirsiniz) :

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

Object.values layner

Son olarak, yorumlarda belirtildiği gibi ve başka bir cevapta teh_senaus tarafından, bunlardan birini şim olarak kullanmaya değer olabilir. Endişelenmeyin, aşağıdakiler prototipi değiştirmez, sadece bir yöntem ekler Object(bu çok daha az tehlikelidir). Yağ-ok işlevlerini kullanarak, bu tek bir satırda da yapılabilir:

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

hangi şimdi kullanabilirsiniz

// ['one', 'two', 'three']
var values = Object.values({ a: 'one', b: 'two', c: 'three' });

Bir yerel Object.valuesvar olduğunda parlamayı önlemek istiyorsanız, şunları yapabilirsiniz:

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

En sonunda...

Desteklemeniz gereken tarayıcıların / sürümlerin farkında olun. Yukarıdaki yöntemler veya dil özellikleri uygulandığında doğrudur. Örneğin, ECMAScript 2015 desteği son zamanlarda V8'de Chrome gibi güçlendirilmiş tarayıcıların bulunduğu varsayılan olarak kapatıldı. ECMAScript 2015'teki özelliklerden, desteklemeyi düşündüğünüz tarayıcılar ihtiyaç duyduğunuz özellikleri uygulayana kadar kullanılmamalıdır. Kodunuzu ECMAScript 5'e derlemek için babel kullanıyorsanız, bu yanıttaki tüm özelliklere erişebilirsiniz.


9
Bu, kabul edilen cevap eksik olduğu için kabul edilen (veya en az daha fazla oylanan) cevap olmalıdır (@olive puanları bu).
0xc0de

Tüm sözde hilelerden bir utanç, yine de objiki kez bahsetmemiz gerekiyor . Yardımcı bir işlev oluşturmak kaçınılmaz mı? Değerler gibi bir şey (obj).
Steven Haryanto

Bu yöntemlerden herhangi biri şim olarak kullanılabilir. Örneğin:Object.values = obj => Object.keys(obj).map(key => obj[key]);
qubyte

1
ECMA 5 çözümleri tüm modern tarayıcılarda çalışmalıdır. ECMA 6 henüz sonuçlandırılmamıştır ve tüm tarayıcılarda destek ön hazırdır. Chrome'da ECMA 6 kısmen uygulandı ancak devre dışı bırakıldı. Firefox'ta destek daha iyidir, ancak dizi anlama yanlıştır (belirtildiği gibi). Gelecekteki zamanı kullanmamın bunu ima edeceğini düşündüm. @JacekLampart, hangi çözüm size hata verdi?
qubyte

2
Neden ES2017 bir Object.values ​​() yöntemi almak için beklemek zorunda düşünemiyorum.
Herbertusz

31

Değerleri bir diziye almak için yeniden kullanılabilir bir işlev. Prototipleri de dikkate alır.

Object.values = function (obj) {
    var vals = [];
    for( var key in obj ) {
        if ( obj.hasOwnProperty(key) ) {
            vals.push(obj[key]);
        }
    }
    return vals;
}

15
Değiştirmek Objectpek sorun değil ( Object.keysortak bir şimdir), muhtemelen Nesne prototipini değiştirmeyi düşünüyorsunuzdur.
kum saati

Neden test etmeniz gerekiyor hasOwnProperty()? Anahtar bu özelliğin döngüsünde nasıl yinelenir?
1252748

4
Google it @homas, önemli. Prototip zincirinden özelliklere sahip olabilir.
Joe

28

Underscore.js'ye erişiminiz varsa, _.valuesişlevi aşağıdaki gibi kullanabilirsiniz :

_.values({one : 1, two : 2, three : 3}); // return [1, 2, 3]

@MathieuAmiot - açıklamak ister misiniz?
Paden

lodash, alt çizgi için api uyumlu bir alternatiftir (daha hızlı).
Mathieu Amiot

@Paden İşte SO ile ilgili bir soru: stackoverflow.com/questions/13789618/…
jichi

2
lodash bunun için gerekli değildir ve kod tabanınızı şişirir
dman

14

Gerçekten bir Değerler dizisi istiyorsanız, bu döngü içinde for ... ile bir dizi oluşturmaktan daha temiz buluyorum.

ECMA 5.1+

function values(o) { return Object.keys(o).map(function(k){return o[k]}) }

Çoğu durumda gerçekten bir değer dizisine ihtiyaç duymadığınızı belirtmek gerekir, bunu yapmak daha hızlı olacaktır:

for(var k in o) something(o[k]);

Bu, Object o'nun anahtarları üzerinde tekrar eder. Her yinelemede k, o anahtarına ayarlanır.


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
Bu neden reddedildi? Bunun en temiz çözümlerden biri olduğunu söyleyebilirim.
Sebastian Hojas

Bilmiyorum, bu niye oy verdi? Bu, herhangi bir kütüphane veya başka bir yardımcı program kullanmadan js'deki en kolay ve en saf çözümdür.
sanjeev shetty

5

Tuşlar arasında geçiş yapabilirsiniz:

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

çıktı olacak:

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

2
Devralınan özniteliklerden kaçınmak istiyorsanız `` hasOwnProperty () '' öğesini de kontrol etmeniz gerekir.
0xc0de

3

CofeeScript çağındaki insanları erken adapte edenler için işte buna başka bir eşdeğer.

val for key,val of objects

Bundan daha iyi olabilir, çünkü objectstekrar yazılacak şekilde azaltılabilir ve okunabilirliği azaltılabilir.

objects[key] for key of objects

3

aşağıdaki gibi bir çoklu dolgu kullanın:

if(!Object.values){Object.values=obj=>Object.keys(obj).map(key=>obj[key])}

sonra kullan

Object.values(my_object)

3) Kâr!



2

Görünüşe göre - yakın zamanda öğrendiğim gibi - bunu yapmanın en hızlı yolu:

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

bunun bir örneğini bir kod kalemi veya jsfiddle koyabilir misiniz? Teşekkürler.
Chris22

2

Soru, kalıtsal ve numaralandırılamayan özelliklerin de istenip istenmediğini belirtmez.

Google'ın kolayca bulamayacağı her şeyi, devralınan mülkleri ve numaralandırılamayan mülkleri almak için bir soru var .

Bunun için benim çözümüm:

function getAllPropertyNames(obj) {
    let result = new Set();
    while (obj) {
        Object.getOwnPropertyNames(obj).forEach(p => result.add(p));
        obj = Object.getPrototypeOf(obj);
    }
    return [...result];
}

Ve sonra tekrarlayın, sadece bir for-loop kullanın:


1

Kullan:, Object.values()bir nesneyi bağımsız değişken olarak iletir ve değerlerin bir dizisini bir dönüş değeri olarak alırız.

Bu, belirli bir nesnenin kendi numaralandırılabilir özellik değerlerinin bir dizisini döndürür. for inDöngüyü kullanmakla aynı değerleri alırsınız, ancak Prototip'in özellikleri olmadan. Bu örnek muhtemelen işleri daha net hale getirecektir:

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

İşte PHP'nin array_values ​​() işlevine benzer bir işlev

function array_values(input) {
  var output = [], key = '';
  for ( key in input ) { output[output.length] = input[key]; }
  return output;
}

ES6 veya üstünü kullanıyorsanız nesnenin değerlerini nasıl alacağınız aşağıda açıklanmıştır:

Array.from(values(obj));

Nedense, değerler () Chrome ve Firefox'ta çalışıyor, ancak iojs / node üzerinde çalışmıyor.
jaggedsoft

0

ES7 ile uyumlu bazı tarayıcılar bile henüz desteklemiyor

Beri Object.values(<object>)yerleşik edilecek yılında ES7 &

Tüm tarayıcıları desteklemek için bekleyene kadar, bir işlevin içine sarabilirsiniz:

Object.vals=(o)=>(Object.values)?Object.values(o):Object.keys(o).map((k)=>o[k])

Sonra :

Object.vals({lastname:'T',firstname:'A'})
 // ['T','A']

Tarayıcılar ES7 ile uyumlu hale geldiğinde, kodunuzdaki hiçbir şeyi değiştirmeniz gerekmez.


0

Biraz geç kaldığımı fark ettim ama işte yeni firefox 47 yöntemi için bir şimObject.values

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

0

Object.entries bunu daha iyi yapar.

  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 }

Tüm değerleri al:

  • en kısa yol:

    • 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

içinde ECMAScript5'i kullanım

 keys = Object.keys(object);

Aksi takdirde tarayıcınız desteklemiyorsa, iyi bilinenleri kullanın for..in loop

for (key in object) {
    // your code here
}

17
Soru anahtarları değil değerleri istiyordu.
zachelrath

@zachelrath Haklısın. - Ancak değerleri almak istiyorsanız bu komut dosyası yararlıdır çünkü anahtarları bildiğinizde object[key]değerleri bir döngüde almak için kullanabilirsiniz .
fridojet

2
@fridojet Ama bu for..in(ve hasOwnProperty) ile yapılabilir, bu yüzden gerçekten bir şey kazanmaz .. Keşke ECMAScript 5. tanımlı Object.pairs(ve Object.itemsiçin [[key, value], ..]), ama ne yazık ki, değil.
user2246674

-8

Şimdi kullanmak Dojo Toolkit eski tarayıcılar desteklemediği için 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);
});

Çıktı :

['1', '2', '3']

5
Açıkçası, dizi doğru değil. Bir sayı dizisi yerine bir dizgi diziniz var.
qubyte

-10

kullanım

console.log(variable)

ve google chrome kullanıyorsanız Ctrl + Shift + j kullanarak Konsolu açın

Git >> Konsol

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.