Soru Bir JavaScript nesnesini nasıl çevirebilirim veya numaralandırırım?


Aşağıdaki gibi bir JavaScript nesnesine sahibim:

var p = {
    "p1": "value1",
    "p2": "value2",
    "p3": "value3"
};

Şimdi ben her şeyden geçmek istiyorum p elementler (p1,p2,p3...) ve anahtarlarını ve değerlerini al. Bunu nasıl yapabilirim?

Gerekirse JavaScript nesnesini değiştirebilirim. Benim nihai hedefim bazı önemli değer çiftleri arasında geçiş yapmaktır ve eğer mümkünse kullanmaktan kaçınmak istiyorum eval.


2133
2018-03-26 06:01


Menşei


Nesne değişmezlerini ve JSON'u karıştırmamak için JSON'u JavaScript (object) olarak değiştirdim. - Felix Kling
Koleksiyon üzerinde yinelenirken, optimizasyonla ilgilenmeniz gerekir. Sayfa performansını etkileyebileceğinden. - Zaheer Ahmed
Güzel Baskı Javascript:  j11y.io/demos/prettyprint  Ben büyük bir hayranıyım boşaltma işlevi  ajaxian.com/archives/javascript-variable-dump-in-coldfusion - Kiquenet
boşaltma işlevi:  github.com/ozmartian/js-cfdump - Kiquenet


Cevaplar:


Kullanabilirsiniz for-in diğerleri tarafından gösterildiği gibi döngü. Bununla birlikte, aldığınız anahtarın bir nesnenin gerçek bir özelliği olduğundan ve prototipten gelmediğinden emin olmanız gerekir.

İşte snippet:

var p = {
    "p1": "value1",
    "p2": "value2",
    "p3": "value3"
};

for (var key in p) {
    if (p.hasOwnProperty(key)) {
        console.log(key + " -> " + p[key]);
    }
}


3467
2018-03-26 06:12



Uyarı çizgisini sadece açıklık sağlamak için değiştirmenizi öneririm alert(key + " -> " + JSON.stringify(p[key])); - Steve Midgley
HasOwnProperty gereksinimini açıklayabilir misiniz? Prototip ile ne demek istiyorsun? - kamaci
Javascript'te, her nesnenin meta-bilgi içeren bir grup yerleşik anahtar-değer çifti vardır. Bir nesnenin tüm anahtar-değer çiftlerini de içine soktuğunuzda, bunlara da bir döngü atfedersiniz. hasOwnPropery () bunları filtreler. - danieltalsky
Aslında, For ... lütfen kullanımdan kaldırılmadı. Her biri için ... olduğunu. Ama ben gerçekten terimden hoşlanıyorum arkeologlar... bunu kullanmaya başlamak zorundayım. - Ben Y
Javascript'teki her nesne (aslında bir anahtar-değer çifti) adlı bir özelliğe sahiptir __proto__ veya prototype. Bu özellik, kendi ana nesnesine bir başvurusu vardır. Bir nesne otomatik olarak mülkünü ana öğesinden devralır. Kullanmanın nedeni budur hasOwnPropertyNesnelerin kendi mülkleriyle ilgilendiğimizi ve ebeveynleriyle ilgilenmediğimizi belirtir. - Zubair Alam


ECMAScript 5 altında birleştirebilirsiniz Object.keys() ve Array.prototype.forEach():

var obj = { first: "John", last: "Doe" };

Object.keys(obj).forEach(function(key) {
    console.log(key, obj[key]);
});

ES6 ekler for...of:

for (const key of Object.keys(obj)) {
    console.log(key, obj[key]);
}

ES2017 ekler Object.entries() Özgün nesnede her bir değere bakmak zorunda kalmadan kaçınıyor:

Object.entries(obj).forEach(
    ([key, value]) => console.log(key, value)
);

Her ikisi de Object.keys() ve Object.entries() özellikleri aynı sırayla yinelemek for...in döngü ama prototip zincirini görmezden gel. Yalnızca nesnenin kendi numaralandırılabilir özellikleri yinelenir.

Düzenleme: ES2016 → ES6


627
2018-04-20 21:59



Standart neden sağlanmadı? Object.forEach(obj, function (value, key) {...})? :( Kesinlikle obj.forEach(function...) daha kısa ve tamamlayıcı olurdu Array.prototype.forEachama bu nesnelerin sahip olma riskini kendileri tanımlar forEach özelliği. sanırım Object.keys nesnenin anahtarlarını değiştiren geri aramalara karşı korur. - David Harkness
Object.forEach = function (obj, callback) { Object.keys(obj).forEach(function (key) { callback(obj[key], key); }); } - David Harkness
@DavidHarkness ES2017'de Object.entries var. Orada aşağıdakileri yapabilirsiniz: Object.entries(obj).map/forEach(([key, value]) => console.log(key, value)) ([anahtar, değer], her iki öğeye de doğrudan erişmek için dizi yıkımıdır. Ayrıca parametreleri ek parantez içinde sarmanız gerekir.) - Andreas Linnert
Nasıl alabilirim index Json'daki anahtarın mı? Ya da gerekirse ayrı bir sayaç kullanmalı mıyım? - Saravanabalagi Ramachandran
for...of ES20 standart değil, ES2016'dır. - Rax Weber


Kullanmalısın for-in döngü

Ama bu tür bir döngü kullanırken çok dikkatli olun, çünkü bu prototip zinciri boyunca tüm özellikleri döngü.

Bu nedenle, for-in döngüleri kullanırken, her zaman hasOwnProperty İterasyondaki geçerli özelliğin gerçekten kontrol ettiğiniz nesnenin bir özelliği olup olmadığını belirleme yöntemi:

for (var prop in p) {
    if (!p.hasOwnProperty(prop)) {
        //The current property is not a direct property of p
        continue;
    }
    //Do your logic with the property here
}

300
2018-03-26 06:12



Bu, levik'in çözümünden daha iyidir çünkü ana mantığın ikiden ziyade bir yuvalanmış döngü olmasını sağlar; kodu okumak daha kolay hale getirmek. Her ne kadar parantezleri devam etsem de; gereksizdirler. - SystemicPlural
Ben kaldırmazdım { } kişisel olarak bir if Onlar olmadan, neyin bir parçası olduğu biraz belirsiz kılıyor if ve ne değil. Ama sanırım bu sadece bir fikir meselesi :) - pimvdb
Evet, tutmayı tercih ederim { } özellikle daha sonra karışıklıklardan kaçınmak için if kapsamı. - Andreas Grech
Önceki yorumumu okuduğumda, doğru şartları kullanmadığımı fark ettim, çünkü “eğer kapsam” dedim; ancak JavaScript'in yalnızca işlev kapsamına sahip olduğunu unutmayın. Yani aslında demek istediğim "blok ise" idi. - Andreas Grech
eomeroff, eğer gerçekten endişeleniyorsan, her zaman böyle bir şey yapabilirsin: Object.prototype.hasOwnProperty.call(p, prop)  Ancak, bu da Object.prototype için manipülasyonlara karşı koruyamaz ... - jordancpaul


Nesneler arasında döngü yapmak için alternatif yöntemlerden bahsetmiyorsak soru tamamlanmayacaktır.

Günümüzde birçok iyi bilinen JavaScript kütüphanesi, koleksiyonlar üzerinde yineleme yapmak için kendi yöntemlerini sunmaktadır, yani diziler, nesneleri, ve dizi benzeri nesneler. Bu yöntemler kullanmak için uygundur ve herhangi bir tarayıcı ile tamamen uyumludur.

  1. Eğer ile çalışırsanız jQuery, kullanabilirsin jQuery.each() yöntem. Hem nesneler hem de diziler üzerinde kesintisiz olarak yinelemek için kullanılabilir:

    $.each(obj, function(key, value) {
        console.log(key, value);
    });
    
  2. İçinde Underscore.js metodu bulabilirsin _.each()öğelerin bir listesi üzerinde yinelenen, her biri sırayla sağlanan bir işleve dönüşen (argümanlar sırasına dikkat edin) iteratee işlev)!:

    _.each(obj, function(value, key) {
        console.log(key, value);
    });
    
  3. Lo-Dash nesne özellikleri üzerinde yinelemek için çeşitli yöntemler sağlar. Temel _.forEach() (veya diğer adı _.each()), hem nesneler hem de diziler arasında döngü yapmak için yararlıdır, ancak (!) length özellik diziler gibi ele alınır ve bu davranıştan kaçınmak için kullanılması önerilir _.forIn() ve _.forOwn() yöntemler (bunlar da var value ilk argüman geliyor:

    _.forIn(obj, function(value, key) {
        console.log(key, value);
    });
    

    _.forIn() tekrarlar kendi ve miras Bir nesnenin sayısız özelliği, _.forOwn() sadece tekrarlar kendi bir nesnenin özellikleri (temelde karşı kontrol hasOwnProperty fonksiyonu). Basit nesneler ve nesne hazırlıkları için, bu yöntemlerden herhangi biri iyi çalışır.

Genel olarak açıklanan tüm yöntemler, sağlanan herhangi bir nesne ile aynı davranışa sahiptir. Yerel kullanımın yanı sıra for..in döngü genellikle olacaktır Daha hızlı gibi herhangi bir soyutlamadan jQuery.each()Bu yöntemler, kullanımı oldukça kolaydır, daha az kodlama gerektirir ve daha iyi hata işleme sağlar.


231
2018-01-20 17:58



Değere ulaşmak için: $ .each (obj, function (anahtar, değer) {console.log (value.title);}); - Ravi Ram
Sadece komik nasıl alt çizgi ve jquery parametrelerini değiştirdi :) - ppasler


ECMAScript 5'te, literal iterasyon alanlarında yeni bir yaklaşımınız var - Object.keys

Görebileceğiniz daha fazla bilgi MDN

Seçimim, tarayıcıların mevcut sürümlerinde daha hızlı bir çözüm olarak aşağıdadır (Chrome30, IE10, FF25)

var keys = Object.keys(p),
    len = keys.length,
    i = 0,
    prop,
    value;
while (i < len) {
    prop = keys[i];
    value = p[prop];
    i += 1;
}

Bu yaklaşımın performansını farklı uygulamalarla karşılaştırabilirsiniz. jsperf.com:

Görebileceğiniz tarayıcı desteği Kangax'ın dostluğu tablosu

Eski tarayıcı için basit ve tam polyfill

UPD:

Bu sorudaki en popüler vakaların tümü için performans karşılaştırması perfjs.info:

nesne değişmezi yineleme


47
2017-11-16 19:59



Gerçekten, sadece bu yöntemi göndermek istedim. Ama sen bana onu yendin :( - Jamie Hutber
jsperf.com/object-iteration-comparison - Jason


Sadece şu şekilde yineleyebilirsiniz:

for (var key in p) {
  alert(p[key]);
}

Bunu not et key mülkün değerini almayacak, sadece bir endeks değeri.


30
2018-03-26 06:05



Bu tekrarlanır ve hatta tamamen doğru değildir. Bunun düzgün çalışması için hasOwnProperty kontrolüne sahip olmanız gerekir. - Vatsal


Es2015 gittikçe daha popüler hale geldiğinden beri, düzgün bir şekilde yinelemek için jeneratör ve yineleyicinin kullanımını içeren bu cevabı yayınlarım [key, value] çiftleri. Diğer dillerde olduğu gibi, örneğin Ruby.

Tamam, bir kod:

const MyObject = {
  'a': 'Hello',
  'b': 'it\'s',
  'c': 'me',
  'd': 'you',
  'e': 'looking',
  'f': 'for',
  [Symbol.iterator]: function* () {
    for (const i of Object.keys(this)) {
      yield [i, this[i]];
    }
  }
};

for (const [k, v] of MyObject) {
  console.log(`Here is key ${k} and here is value ${v}`);
}

Geliştirici Mozilla sayfasında bulabilirsiniz bir yineleyici ve jeneratör nasıl yapabilirsiniz hakkında tüm bilgiler.

Umarım birisine yardım eder.

DÜZENLE:

ES2017 içerecek Object.entries hangi üzerinde yineleme yapacak [key, value] nesnelerdeki çiftler daha da kolay. Artık standartlara göre bir standardın parçası olacağı bilinmektedir. ts39 sahne bilgisi

Cevabımı güncellemenin, şimdi olduğundan daha da taze olmasına izin vermenin zamanı geldiğini düşünüyorum.

const MyObject = {
  'a': 'Hello',
  'b': 'it\'s',
  'c': 'me',
  'd': 'you',
  'e': 'looking',
  'f': 'for',
};

for (const [k, v] of Object.entries(MyObject)) {
  console.log(`Here is key ${k} and here is value ${v}`);
}

Kullanım hakkında daha fazla bilgi edinebilirsiniz. MDN sayfa


24
2017-08-27 09:06



teşekkür ederim! şimdi benim meslektaşlarım 2005 tarzı JS için bana alay etmeyecek! - the0ther
Bu tamamen gereksiz / bana gereksiz görünüyor. Sisteminizdeki her nesneye ekler misiniz? Bir yineleyicinin sağlanması noktasını düşündüm ki, 'için yapabilecektim (const [k, v] myObject)'. Sadece ek bir değer sağlayan ekstra kod gibi görünüyor. - Dean Radcliffe