Sto provando ad accedere a una proprietà di un oggetto usando un nome dinamico. È possibile?
const something = { bar: "Foobar!" };
const foo = 'bar';
something.foo; // The idea is to access something.bar, getting "Foobar!"
Sto provando ad accedere a una proprietà di un oggetto usando un nome dinamico. È possibile?
const something = { bar: "Foobar!" };
const foo = 'bar';
something.foo; // The idea is to access something.bar, getting "Foobar!"
Risposte:
Esistono due modi per accedere alle proprietà di un oggetto:
something.bar
something['bar']
Il valore tra parentesi può essere qualsiasi espressione. Pertanto, se il nome della proprietà è memorizzato in una variabile, è necessario utilizzare la notazione parentesi:
var foo = 'bar';
something[foo];
// both x = something[foo] and something[foo] = x work as expected
Questa è la mia soluzione:
function resolve(path, obj) {
return path.split('.').reduce(function(prev, curr) {
return prev ? prev[curr] : null
}, obj || self)
}
Esempi di utilizzo:
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'})
In javascript possiamo accedere con:
foo.bar
foo[someVar]
oppurefoo["string"]
Ma solo il secondo caso consente di accedere dinamicamente alle proprietà:
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
Di seguito è riportato un esempio ES6 di come è possibile accedere alla proprietà di un oggetto utilizzando un nome di proprietà che è stato generato dinamicamente concatenando due stringhe.
var suffix = " name";
var person = {
["first" + suffix]: "Nicholas",
["last" + suffix]: "Zakas"
};
console.log(person["first name"]); // "Nicholas"
console.log(person["last name"]); // "Zakas"
Questo si chiama nomi di proprietà calcolati
Puoi ottenerlo in diversi modi.
let foo = {
bar: 'Hello World'
};
foo.bar;
foo['bar'];
La notazione parentesi è particolarmente potente in quanto consente di accedere a una proprietà in base a una variabile:
let foo = {
bar: 'Hello World'
};
let prop = 'bar';
foo[prop];
Questo può essere esteso al ciclo su ogni proprietà di un oggetto. Questo può sembrare ridondante a causa di costrutti JavaScript più recenti come per ... di ..., ma aiuta a illustrare un caso d'uso:
let foo = {
bar: 'Hello World',
baz: 'How are you doing?',
last: 'Quite alright'
};
for (let prop in foo.getOwnPropertyNames()) {
console.log(foo[prop]);
}
Anche la notazione punto e parentesi funziona come previsto per gli oggetti nidificati:
let foo = {
bar: {
baz: 'Hello World'
}
};
foo.bar.baz;
foo['bar']['baz'];
foo.bar['baz'];
foo['bar'].baz;
Distruzione dell'oggetto
Potremmo anche considerare la distruzione degli oggetti come un mezzo per accedere a una proprietà in un oggetto, ma come segue:
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'
Puoi farlo in questo modo usando Lodash get
_.get(object, 'a[0].b.c');
Ho preso in considerazione i seguenti commenti e ho concordato. Eval deve essere evitato.
L'accesso alle proprietà della radice nell'oggetto è facilmente raggiungibile con obj[variable]
, ma l'annidamento complica la cosa. Non scrivere codice già scritto che consiglio di usare lodash.get
.
Esempio
// Accessing root property
var rootProp = 'rootPropert';
_.get(object, rootProp, defaultValue);
// Accessing nested property
var listOfNestedProperties = [var1, var2];
_.get(object, listOfNestedProperties);
Lodash get può essere utilizzato in diversi modi, qui è presente il collegamento alla documentazione lodash.get
eval
quando possibile. stackoverflow.com/questions/86513/…
eval
qualcosa di banale come accedere alle proprietà è eccessivo e difficilmente consigliabile in qualsiasi circostanza. Che cos'è "guai"? obj['nested']['test']
funziona molto bene e non richiede di incorporare il codice nelle stringhe.
obj['nested']['value']
- ricorda i bambini, eval è malvagio!
_.get
al tavolo. Penso che questa risposta meriti adesso voti invece di voti negativi. Potrebbe essere eccessivo, ma è bene sapere che esiste.
Ogni volta che devi accedere dinamicamente alla proprietà, devi usare la parentesi quadra per accedere alla proprietà non "." sintassi dell'operatore
: object [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])
Mi sono imbattuto in un caso in cui ho pensato voler passare l '"indirizzo" di una proprietà dell'oggetto come dati a un'altra funzione e popolare l'oggetto (con AJAX), cercare dall'array di indirizzi e visualizzarlo in quell'altra funzione. Non potevo usare la notazione a punti senza fare acrobazie a stringa, quindi pensavo che un array potesse essere bello da passare. Alla fine ho fatto qualcosa di diverso, ma mi è sembrato correlato a questo post.
Ecco un esempio di un oggetto file di lingua come quello da cui volevo i dati:
const locs = {
"audioPlayer": {
"controls": {
"start": "start",
"stop": "stop"
},
"heading": "Use controls to start and stop audio."
}
}
Volevo essere in grado di passare un array come: ["audioPlayer", "controlli", "stop"] per accedere al testo della lingua, "stop" in questo caso.
Ho creato questa piccola funzione che cerca il parametro "primo" (primo) indirizzo e riassegna l'oggetto restituito a se stesso. Quindi è pronto per cercare il parametro di indirizzo più specifico successivo se ne esiste uno.
function getText(selectionArray, obj) {
selectionArray.forEach(key => {
obj = obj[key];
});
return obj;
}
utilizzo:
/* returns 'stop' */
console.log(getText(["audioPlayer", "controls", "stop"], locs));
/* returns 'use controls to start and stop audio.' */
console.log(getText(["audioPlayer", "heading"], locs));
Diventa interessante anche quando devi passare parametri a questa funzione.
Codice 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
Questo semplice pezzo di codice può verificare l'esistenza di variabili / valori profondamente nidificati senza dover controllare ogni variabile lungo il percorso ...
var getValue = function( s, context ){
return Function.call( context || null, 'return ' + s )();
}
Ex. - una matrice di oggetti profondamente annidata:
a = [
{
b : [
{
a : 1,
b : [
{
c : 1,
d : 2 // we want to check for this
}
]
}
]
}
]
Invece di :
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
Ora possiamo:
if( getValue('a[0].b[0].b[0].d') == 2 ) // true
Saluti!
Ho fatto una domanda che in qualche modo è stata duplicata su questo argomento qualche tempo fa, e dopo un'eccessiva ricerca, e vedendo molte informazioni mancanti che dovrebbero essere qui, sento di avere qualcosa di prezioso da aggiungere a questo post più vecchio.
let properyValue = element.style['enter-a-property'];
tuttavia raramente seguo questa strada perché non funziona sui valori delle proprietà assegnati tramite fogli di stile. Per fare un esempio, lo dimostrerò con un po 'di pseudo codice.
let elem = document.getElementById('someDiv');
let cssProp = elem.style['width'];
Utilizzando l'esempio di codice sopra; se la proprietà width dell'elemento div che è stato memorizzato nella variabile 'elem' è stata disegnata in un foglio di stile CSS e non all'interno del suo tag HTML, senza dubbio otterrai un valore di ritorno di un archivio non definito della variabile cssProp. Il valore indefinito si verifica perché per ottenere il valore corretto, al fine di ottenere il valore, il codice scritto all'interno di un foglio di stile CSS deve essere calcolato per ottenere il valore; è necessario utilizzare un metodo che calcolerà il valore della proprietà il cui valore si trova all'interno del foglio di stile.
function getCssProp(){
let ele = document.getElementById("test");
let cssProp = window.getComputedStyle(ele,null).getPropertyValue("width");
}
W3Schools getComputedValue Doc Questo fornisce un buon esempio e ti consente di giocarci, tuttavia, questo link Mozilla CSS getComputedValue doc parla in dettaglio della funzione getComputedValue e dovrebbe essere letto da qualsiasi aspirante sviluppatore che non sia del tutto chiaro su questo argomento.
$(selector).css(property,value)
... ottiene e imposta. È quello che uso, l'unico aspetto negativo è che hai conosciuto JQuery, ma questo è onestamente uno dei tanti buoni motivi per cui ogni sviluppatore di Javascript dovrebbe imparare JQuery, semplifica la vita e offre metodi come questo, che non è disponibile con Javascript standard. Spero che questo aiuti qualcuno !!!
Per chiunque cerchi di impostare il valore di una variabile nidificata, ecco come farlo:
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
Documentazione: https://lodash.com/docs/4.17.15#set
Inoltre, la documentazione se si desidera ottenere un valore: https://lodash.com/docs/4.17.15#get
Dovresti usare JSON.parse
, dai un'occhiata a 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
è già una stringa, quindi `${foo}`
è esattamente la stessa di foo
. (Inoltre, il tuo codice sembra avere alcune barre rovesciate extra che non appartengono a questo. Ma sarebbe comunque inutile anche se correggessi l'errore di sintassi.)