javascript - Nokta notasyonu stringi kullanarak nesne alt özelliklerine erişim
Geçici olarak çok basit görünüyor bir JavaScript problemi ile takıldım, ama belki de doğru arama anahtar kelimelerini kaçırıyorum!
Diyelim ki bir nesnemiz var
var r = { a:1, b: {b1:11, b2: 99}};
99'a erişmenin birkaç yolu vardır:
r.b.b2
r['b']['b2']
İstediğim şey bir string tanımlayabilmek
var s = "b.b2";
ve sonra 99'u kullanarak erişin
r.s or r[s] //(which of course won't work)
Bunun için bir yol, noktada bölünmüş bir string üzerinde çalışan ve belki de özelliği özyinelemeli/iteratif olarak alan bir fonksiyon yazmaktır. Ama daha basit/daha verimli bir yol var mı? Burada jQuery API’lerinden herhangi biri faydalı olur mu?
Cevap #1
Bir süre önce yazdığım saf bir fonksiyon işte, ama temel nesne özellikleri için çalışıyor:
function getDescendantProp(obj, desc) {
var arr = desc.split(".");
while(arr.length && (obj = obj[arr.shift()]));
return obj;
}
console.log(getDescendantProp(r, "b.b2"));
//-> 99
Buna "izin ver" dizi indeks erişimini uzatan yanıtlar olsa da, bu aslında gerekli değil çünkü bu yöntemle yalnızca sayısal indeksleri nokta gösterimi kullanarak belirtebilirsiniz:
getDescendantProp({ a: [ 1, 2, 3 ] }, 'a.2');
//-> 3
Cevap #2
split ve reduce ile nesneyi initalValue olarak geçirirken
Güncelleme (TeChn4K tarafından yapılan yoruma teşekkürler)
ES6 sözdizimi ile, bu daha da kısadır
var r = { a:1, b: {b1:11, b2: 99}};
var s = "b.b2";
var value = s.split('.').reduce((a, b) => a[b], r);
console.log(value);Eski sürüm
var r = { a:1, b: {b1:11, b2: 99}};
var s = "b.b2";
var value = s.split('.').reduce(function(a, b) {
return a[b];
}, r);
console.log(value);Cevap #3
Lodash get() ve set() yöntemlerini kullanabilirsiniz.
Almak
var object = { 'a': [{ 'b': { 'c': 3 } }] };
_.get(object, 'a[0].b.c');
// → 3
Kurulum
var object = { 'a': [{ 'b': { 'c': 3 } }] };
_.set(object, 'a[0].b.c', 4);
console.log(object.a[0].b.c);
// → 4
Cevap #4
Senin senaryonda, hedeflediğin tüm dizi değişkenini bir string içine koyman mümkünse, eval() fonksiyonunu kullanabilirsin.
var r = { a:1, b: {b1:11, b2: 99}};
var s = "r.b.b2";
alert(eval(s)); // 99
İnsanların dehşet içinde sarsıldığını hissedebiliyorum
Cevap #5
@JohnB'nin cevabını genişleterek, ben de bir setter değeri ekledim. Plunkr'a göz atın
http://plnkr.co/edit/lo0thC?p=preview
function getSetDescendantProp(obj, desc, value) {
var arr = desc ? desc.split(".") : [];
while (arr.length && obj) {
var comp = arr.shift();
var match = new RegExp("(.+)\\[([0-9]*)\\]").exec(comp);
// handle arrays
if ((match !== null) && (match.length == 3)) {
var arrayData = {
arrName: match[1],
arrIndex: match[2]
};
if (obj[arrayData.arrName] !== undefined) {
if (typeof value !== 'undefined' && arr.length === 0) {
obj[arrayData.arrName][arrayData.arrIndex] = value;
}
obj = obj[arrayData.arrName][arrayData.arrIndex];
} else {
obj = undefined;
}
continue;
}
// handle regular things
if (typeof value !== 'undefined') {
if (obj[comp] === undefined) {
obj[comp] = {};
}
if (arr.length === 0) {
obj[comp] = value;
}
}
obj = obj[comp];
}
return obj;
}
