Dinamik bir ad kullanarak bir nesnenin özelliğine erişmeye çalışıyorum. Mümkün mü?
const something = { bar: "Foobar!" };
const foo = 'bar';
something.foo; // The idea is to access something.bar, getting "Foobar!"
Dinamik bir ad kullanarak bir nesnenin özelliğine erişmeye çalışıyorum. Mümkün mü?
const something = { bar: "Foobar!" };
const foo = 'bar';
something.foo; // The idea is to access something.bar, getting "Foobar!"
Yanıtlar:
Bir nesnenin özelliklerine erişmenin iki yolu vardır :
something.bar
something['bar']
Köşeli ayraçlar arasındaki değer herhangi bir ifade olabilir. Bu nedenle, özellik adı bir değişkende depolanırsa, parantez notasyonu kullanmanız gerekir:
var foo = 'bar';
something[foo];
// both x = something[foo] and something[foo] = x work as expected
Bu benim çözümüm:
function resolve(path, obj) {
return path.split('.').reduce(function(prev, curr) {
return prev ? prev[curr] : null
}, obj || self)
}
Kullanım örnekleri:
resolve("document.body.style.width")
// or
resolve("style.width", document.body)
// or even use array indexes
// (someObject has been defined in the question)
resolve("part.0.size", someObject)
// returns null when intermediate properties are not defined:
resolve('properties.that.do.not.exist', {hello:'world'})
Javascript ile şunlara erişebiliriz:
foo.bar
foo[someVar]
veyafoo["string"]
Ancak yalnızca ikinci durum, özelliklere dinamik olarak erişmeyi sağlar:
var foo = { pName1 : 1, pName2 : [1, {foo : bar }, 3] , ...}
var name = "pName"
var num = 1;
foo[name + num]; // 1
// --
var a = 2;
var b = 1;
var c = "foo";
foo[name + a][b][c]; // bar
Aşağıda, iki dizeyi birleştirerek dinamik olarak oluşturulmuş bir özellik adını kullanarak bir nesnenin özelliğine nasıl erişebileceğinize ilişkin bir ES6 örneği verilmiştir.
var suffix = " name";
var person = {
["first" + suffix]: "Nicholas",
["last" + suffix]: "Zakas"
};
console.log(person["first name"]); // "Nicholas"
console.log(person["last name"]); // "Zakas"
Buna hesaplanmış özellik adları denir
Bunu birkaç farklı yolla başarabilirsiniz.
let foo = {
bar: 'Hello World'
};
foo.bar;
foo['bar'];
Köşeli ayraç notasyonu, bir değişkene dayalı bir özelliğe erişmenize izin verdiği için özellikle güçlüdür:
let foo = {
bar: 'Hello World'
};
let prop = 'bar';
foo[prop];
Bu, bir nesnenin her özelliği üzerinde döngü oluşturacak şekilde genişletilebilir. Bu, ... gibi ... gibi daha yeni JavaScript yapıları nedeniyle gereksiz görünebilir, ancak bir kullanım durumunu göstermeye yardımcı olur:
let foo = {
bar: 'Hello World',
baz: 'How are you doing?',
last: 'Quite alright'
};
for (let prop in foo.getOwnPropertyNames()) {
console.log(foo[prop]);
}
Hem nokta hem de köşeli gösterim, iç içe geçmiş nesneler için beklendiği gibi çalışır:
let foo = {
bar: {
baz: 'Hello World'
}
};
foo.bar.baz;
foo['bar']['baz'];
foo.bar['baz'];
foo['bar'].baz;
Nesne yok etme
Nesne yok etmeyi, bir nesnedeki bir özelliğe erişmek için bir araç olarak da düşünebiliriz, ancak aşağıdaki gibi:
let foo = {
bar: 'Hello World',
baz: 'How are you doing?',
last: 'Quite alright'
};
let prop = 'last';
let { bar, baz, [prop]: customName } = foo;
// bar = 'Hello World'
// baz = 'How are you doing?'
// customName = 'Quite alright'
Bunu Lodash get kullanarak böyle yapabilirsiniz
_.get(object, 'a[0].b.c');
Aşağıdaki yorumları dikkate aldım ve kabul ettim. Değerlendirmeden kaçınılmalıdır.
Nesnede kök özelliklerine erişmek ile kolayca elde edilir obj[variable]
, ancak iç içe geçmek bir şeyi zorlaştırır. Zaten yazılı kod yazmamak için kullanmanızı öneririm lodash.get
.
Misal
// Accessing root property
var rootProp = 'rootPropert';
_.get(object, rootProp, defaultValue);
// Accessing nested property
var listOfNestedProperties = [var1, var2];
_.get(object, listOfNestedProperties);
Lodash get farklı şekillerde kullanılabilir, işte lodash.get belgelerine bağlantı
eval
Mümkün olduğunca kullanmaktan kaçınmak en iyisidir . stackoverflow.com/questions/86513/…
eval
Özelliklere erişim kadar önemsiz bir şey kullanmak , aşırıya kaçar ve hiçbir koşulda tavsiye edilemez. "Sorun" nedir? obj['nested']['test']
çok iyi çalışır ve kodu dizelere yerleştirmenizi gerektirmez.
obj['nested']['value']
- çocukları hatırlayın, eval kötülüktür!
_.get
masaya getirmek isteyen tek kişi o. Bence bu cevap şimdi aşağı oy yerine yukarı oy hak ediyor. Aşırı olabilir, ama var olduğunu bilmek güzel.
Özelliğe dinamik olarak erişmeniz gerektiğinde, özelliğe "değil" erişmek için köşeli parantez kullanmanız gerekir. operatör
Sözdizimi: nesne [uygunluk}
const something = { bar: "Foobar!" };
const foo = 'bar';
// something.foo; -- not correct way at it is expecting foo as proprty in something={ foo: "value"};
// correct way is something[foo]
alert( something[foo])
Düşündüğüm bir davaya rastladım , bu diğer işlevinde adres dizisi ve ekrana gelen arama yapmak başka işleve veri olarak bir nesne özelliğinin "adresi" geçmek istediğini ve (AJAX ile) nesnesini doldurmak. Ben dizi akrobasi yapmadan nokta gösterimi kullanamadı bu yüzden bir dizi yerine geçmek güzel olabilir düşündüm. Yine de farklı bir şey yaptım ama bu yazı ile ilgili görünüyordu.
İşte veri istediğim gibi bir dil dosyası nesnesinin bir örneği:
const locs = {
"audioPlayer": {
"controls": {
"start": "start",
"stop": "stop"
},
"heading": "Use controls to start and stop audio."
}
}
Böyle bir diziyi geçmek istedim: ["audioPlayer", "kontroller", "dur"] dil metnine erişmek için, "bu durumda" dur.
"En az belirli" (ilk) adres parametresini arar ve döndürülen nesneyi kendisine yeniden atar bu küçük işlevi oluşturdu. Ardından, varsa en sonraki adres parametresini aramaya hazırdır.
function getText(selectionArray, obj) {
selectionArray.forEach(key => {
obj = obj[key];
});
return obj;
}
kullanımı:
/* returns 'stop' */
console.log(getText(["audioPlayer", "controls", "stop"], locs));
/* returns 'use controls to start and stop audio.' */
console.log(getText(["audioPlayer", "heading"], locs));
Bu işleve de parametreler iletmeniz gerektiğinde ilginç hale gelir.
Kod jsfiddle
var obj = {method:function(p1,p2,p3){console.log("method:",arguments)}}
var str = "method('p1', 'p2', 'p3');"
var match = str.match(/^\s*(\S+)\((.*)\);\s*$/);
var func = match[1]
var parameters = match[2].split(',');
for(var i = 0; i < parameters.length; ++i) {
// clean up param begninning
parameters[i] = parameters[i].replace(/^\s*['"]?/,'');
// clean up param end
parameters[i] = parameters[i].replace(/['"]?\s*$/,'');
}
obj[func](parameters); // sends parameters as array
obj[func].apply(this, parameters); // sends parameters as individual values
Bu basit kod parçası, her değişkeni yol boyunca kontrol etmek zorunda kalmadan derin iç içe değişken / değer varlığını kontrol edebilir ...
var getValue = function( s, context ){
return Function.call( context || null, 'return ' + s )();
}
Ör. - derin yuvalanmış bir nesne dizisi:
a = [
{
b : [
{
a : 1,
b : [
{
c : 1,
d : 2 // we want to check for this
}
]
}
]
}
]
Onun yerine :
if(a && a[0] && a[0].b && a[0].b[0] && a[0].b[0].b && a[0].b[0].b[0] && a[0].b[0].b[0].d && a[0].b[0].b[0].d == 2 ) // true
Şimdi yapabiliriz:
if( getValue('a[0].b[0].b[0].d') == 2 ) // true
Şerefe!
Bir süre önce bu konuda tekrarlanan bir soru sordum ve aşırı araştırmadan sonra ve burada olması gereken çok fazla bilgi eksik olduğunu gördüm, bu eski yazıya eklemek için değerli bir şeyim olduğunu hissediyorum.
let properyValue = element.style['enter-a-property'];
Ancak, stil sayfaları aracılığıyla atanan özellik değerleri üzerinde çalışmadığından nadiren bu rotaya giderim. Size bir örnek vermek gerekirse, biraz sahte kodla göstereceğim.
let elem = document.getElementById('someDiv');
let cssProp = elem.style['width'];
Yukarıdaki kod örneğini kullanarak; 'elem' değişkeninde depolanan div öğesinin width özelliği bir CSS stil sayfasında stilize edilmişse ve HTML etiketinin içinde biçimlendirilmemişse, kuşkusuz içinde depolanmış tanımsız bir dönüş değeri elde edersiniz cssProp değişkeni. Tanımlanmamış değer, doğru değeri elde etmek için, bir CSS Stil Sayfası içinde yazılan kodun değeri almak için sırayla hesaplanması gerektiğinden oluşur; değeri stil sayfasında yer alan özelliğin değerini hesaplayacak bir yöntem kullanmalısınız.
function getCssProp(){
let ele = document.getElementById("test");
let cssProp = window.getComputedStyle(ele,null).getPropertyValue("width");
}
W3Schools getComputedValue Doc Bu iyi bir örnek verir ve onunla oynamanıza izin verir, ancak bu bağlantı Mozilla CSS getComputedValue dokümanı getComputedValue işlevinden ayrıntılı olarak bahseder ve bu konuda tamamen net olmayan herhangi bir istekli geliştirici tarafından okunmalıdır.
$(selector).css(property,value)
... alır ve ayarlanır. Kullandığım şey, tek dezavantajı JQuery'yi tanımanızdır, ancak bu dürüst olmak gerekirse, her Javascript Geliştiricisinin JQuery'yi öğrenmesi gereken çok iyi nedenlerden biridir, sadece hayatı kolaylaştırır ve bunun gibi yöntemler sunar, standart Javascript ile kullanılamaz. Umarım bu birine yardımcı olur !!!
Yuvalanmış bir değişkenin değerini ayarlamak isteyen herkes için, nasıl yapılacağı aşağıda açıklanmıştır:
const _ = require('lodash'); //import lodash module
var object = { 'a': [{ 'b': { 'c': 3 } }] };
_.set(object, 'a[0].b.c', 4);
console.log(object.a[0].b.c);
// => 4
Belgeler: https://lodash.com/docs/4.17.15#set
Ayrıca, bir değer almak istiyorsanız belgeler: https://lodash.com/docs/4.17.15#get
Kullanmalı JSON.parse
, https://www.w3schools.com/js/js_json_parse.asp adresine göz atmalısınız.
const obj = JSON.parse('{ "name":"John", "age":30, "city":"New York"}')
console.log(obj.name)
console.log(obj.age)
const something = { bar: "Foobar!" };
const foo = 'bar';
something[\`${foo}\`];
foo
zaten bir dize, yani `${foo}`
tam olarak aynı olduğunu foo
. (Ayrıca, kodunuzun oraya ait olmayan bazı ters eğik çizgiler var gibi görünüyor. Ancak sözdizimi hatasını düzeltseniz bile yine de anlamsız olurdu.)