Próbuję uzyskać dostęp do właściwości obiektu przy użyciu nazwy dynamicznej. czy to możliwe?
const something = { bar: "Foobar!" };
const foo = 'bar';
something.foo; // The idea is to access something.bar, getting "Foobar!"
Próbuję uzyskać dostęp do właściwości obiektu przy użyciu nazwy dynamicznej. czy to możliwe?
const something = { bar: "Foobar!" };
const foo = 'bar';
something.foo; // The idea is to access something.bar, getting "Foobar!"
Odpowiedzi:
Istnieją dwa sposoby uzyskania dostępu do właściwości obiektu:
something.bar
something['bar']
Wartość w nawiasach kwadratowych może być dowolnym wyrażeniem. Dlatego jeśli nazwa właściwości jest przechowywana w zmiennej, musisz użyć notacji nawiasowej:
var foo = 'bar';
something[foo];
// both x = something[foo] and something[foo] = x work as expected
To jest moje rozwiązanie:
function resolve(path, obj) {
return path.split('.').reduce(function(prev, curr) {
return prev ? prev[curr] : null
}, obj || self)
}
Przykłady użycia:
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'})
W javascript możemy uzyskać dostęp za pomocą:
foo.bar
foo[someVar]
lubfoo["string"]
Ale tylko drugi przypadek pozwala na dynamiczny dostęp do właściwości:
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
Poniżej znajduje się przykład ES6, w jaki sposób można uzyskać dostęp do właściwości obiektu za pomocą nazwy właściwości, która została dynamicznie wygenerowana przez połączenie dwóch łańcuchów.
var suffix = " name";
var person = {
["first" + suffix]: "Nicholas",
["last" + suffix]: "Zakas"
};
console.log(person["first name"]); // "Nicholas"
console.log(person["last name"]); // "Zakas"
Nazywa się to obliczonymi nazwami właściwości
Możesz to osiągnąć na kilka różnych sposobów.
let foo = {
bar: 'Hello World'
};
foo.bar;
foo['bar'];
Notacja w nawiasie jest szczególnie wydajna, ponieważ umożliwia dostęp do właściwości opartej na zmiennej:
let foo = {
bar: 'Hello World'
};
let prop = 'bar';
foo[prop];
Można to rozszerzyć na zapętlenie każdej właściwości obiektu. Może to wydawać się zbędne ze względu na nowsze konstrukcje JavaScript, takie jak ... z ..., ale pomaga zilustrować przypadek użycia:
let foo = {
bar: 'Hello World',
baz: 'How are you doing?',
last: 'Quite alright'
};
for (let prop in foo.getOwnPropertyNames()) {
console.log(foo[prop]);
}
Zarówno notacja kropkowa jak i nawiasowa działają również zgodnie z oczekiwaniami dla zagnieżdżonych obiektów:
let foo = {
bar: {
baz: 'Hello World'
}
};
foo.bar.baz;
foo['bar']['baz'];
foo.bar['baz'];
foo['bar'].baz;
Niszczenie obiektów
Możemy również rozważyć destrukcję obiektu jako sposób dostępu do właściwości w obiekcie, ale w następujący sposób:
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'
Możesz to zrobić za pomocą Lodash get
_.get(object, 'a[0].b.c');
Uwzględniłem poniższe uwagi i zgodziłem się. Ewaluacji należy unikać.
Łatwo można uzyskać dostęp do właściwości katalogu głównego w obiekcie obj[variable]
, ale zagnieżdżenie komplikuje sprawę. Nie pisać już napisanego kodu, którego sugeruję użyć lodash.get
.
Przykład
// Accessing root property
var rootProp = 'rootPropert';
_.get(object, rootProp, defaultValue);
// Accessing nested property
var listOfNestedProperties = [var1, var2];
_.get(object, listOfNestedProperties);
Z Lodash get można korzystać na różne sposoby, tutaj jest link do dokumentacji lodash.get
eval
gdy tylko jest to możliwe. stackoverflow.com/questions/86513/…
eval
czegoś tak trywialnego, jak dostęp do właściwości, jest zwykłym przesadą i nie jest zalecane w żadnych okolicznościach. Co to za „kłopoty”? obj['nested']['test']
działa bardzo dobrze i nie wymaga osadzania kodu w łańcuchach.
obj['nested']['value']
- pamiętajcie dzieci, eval jest złe!
_.get
do stołu. Myślę, że ta odpowiedź zasługuje teraz na głosowanie zamiast głosowania negatywnego. Może to być przesada, ale dobrze wiedzieć, że istnieje.
Ilekroć potrzebujesz dynamicznego dostępu do właściwości, musisz użyć nawiasu kwadratowego, aby uzyskać dostęp do właściwości, a nie „.” operator
Składnia: obiekt [propery}
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])
Natknąłem się na przypadek, w którym myślałem, że chcę przekazać „adres” właściwości obiektu jako dane do innej funkcji i zapełnić obiekt (za pomocą AJAX), wyszukać z tablicy adresów i wyświetlić w tej innej funkcji. Nie mogłem używać notacji kropkowej bez robienia akrobatyki łańcuchowej, więc pomyślałem, że tablica może być miło przekazać Skończyło się na zrobieniu czegoś innego, ale wydawało mi się, że jestem związany z tym postem.
Oto przykład obiektu pliku językowego, takiego jak ten, z którego chciałem uzyskać dane:
const locs = {
"audioPlayer": {
"controls": {
"start": "start",
"stop": "stop"
},
"heading": "Use controls to start and stop audio."
}
}
Chciałem móc przekazać tablicę, taką jak: [„audioPlayer”, „kontroluje”, „stop”], aby uzyskać dostęp do tekstu języka, w tym przypadku „stop”.
Stworzyłem tę małą funkcję, która wyszukuje „najmniej konkretny” (pierwszy) parametr adresu i ponownie przypisuje zwracany obiekt do siebie. Następnie jest gotowy wyszukać najbardziej szczegółowy parametr adresu, jeśli taki istnieje.
function getText(selectionArray, obj) {
selectionArray.forEach(key => {
obj = obj[key];
});
return obj;
}
stosowanie:
/* returns 'stop' */
console.log(getText(["audioPlayer", "controls", "stop"], locs));
/* returns 'use controls to start and stop audio.' */
console.log(getText(["audioPlayer", "heading"], locs));
To staje się interesujące, gdy musisz przekazać parametry również do tej funkcji.
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
Ten prosty fragment kodu może sprawdzić głęboko zagnieżdżone istnienie zmiennych / wartości bez konieczności sprawdzania każdej zmiennej po drodze ...
var getValue = function( s, context ){
return Function.call( context || null, 'return ' + s )();
}
Dawny. - głęboko zagnieżdżona tablica obiektów:
a = [
{
b : [
{
a : 1,
b : [
{
c : 1,
d : 2 // we want to check for this
}
]
}
]
}
]
Zamiast :
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
Możemy teraz:
if( getValue('a[0].b[0].b[0].d') == 2 ) // true
Twoje zdrowie!
Zadałem pytanie, które trochę powielało ten temat jakiś czas temu, a po nadmiernych badaniach i widząc wiele brakujących informacji, które powinny tu być, czuję, że mam coś cennego do dodania do tego starszego postu.
let properyValue = element.style['enter-a-property'];
jednak rzadko wybieram tę trasę, ponieważ nie działa ona na wartości właściwości przypisane za pomocą arkuszy stylów. Jako przykład podam przykład z pseudo-kodem.
let elem = document.getElementById('someDiv');
let cssProp = elem.style['width'];
Korzystając z powyższego przykładu kodu; jeśli właściwość width elementu div, który był przechowywany w zmiennej „elem”, została stylizowana w arkuszu stylów CSS, a nie w jej znaczniku HTML, bez wątpienia otrzymasz zwrot wartości niezdefiniowanej przechowywanej w środku zmiennej cssProp. Nieokreślona wartość występuje, ponieważ aby uzyskać poprawną wartość, kod zapisany w arkuszu stylów CSS musi zostać obliczony w celu uzyskania wartości; musisz użyć metody, która obliczy wartość właściwości, której wartość leży w arkuszu stylów.
function getCssProp(){
let ele = document.getElementById("test");
let cssProp = window.getComputedStyle(ele,null).getPropertyValue("width");
}
W3Schools getComputedValue Doc Daje to dobry przykład i pozwala się z nim bawić, jednak ten link Mozilla CSS getComputedValue doc mówi szczegółowo o funkcji getComputedValue i powinien być czytany przez każdego początkującego programistę, który nie jest do końca jasny na ten temat.
$(selector).css(property,value)
... dostaje i ustawia. To jest to, czego używam, jedynym minusem jest to, że znasz JQuery, ale jest to szczerze jeden z wielu dobrych powodów, dla których każdy programista Javascript powinien uczyć się JQuery, ułatwia życie i oferuje metody, takie jak ta, która nie jest dostępny ze standardowym Javascript. Mam nadzieję, że to komuś pomoże !!!
Dla każdego, kto chce ustawić wartość zagnieżdżonej zmiennej, oto jak to zrobić:
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
Dokumentacja: https://lodash.com/docs/4.17.15#set
Ponadto dokumentacja, jeśli chcesz uzyskać wartość: https://lodash.com/docs/4.17.15#get
Powinieneś użyć JSON.parse
, spójrz na https://www.w3schools.com/js/js_json_parse.asp
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
jest już ciągiem, więc `${foo}`
jest dokładnie taki sam jak foo
. (Poza tym twój kod wydaje się zawierać dodatkowe ukośniki odwrotne, które tam nie należą. Ale i tak byłby bezcelowy, nawet jeśli naprawiłeś ten błąd składniowy.)