Ich versuche, mit einem dynamischen Namen auf eine Eigenschaft eines Objekts zuzugreifen. Ist das möglich?
const something = { bar: "Foobar!" };
const foo = 'bar';
something.foo; // The idea is to access something.bar, getting "Foobar!"
Ich versuche, mit einem dynamischen Namen auf eine Eigenschaft eines Objekts zuzugreifen. Ist das möglich?
const something = { bar: "Foobar!" };
const foo = 'bar';
something.foo; // The idea is to access something.bar, getting "Foobar!"
Antworten:
Es gibt zwei Möglichkeiten, auf Eigenschaften eines Objekts zuzugreifen :
something.bar
something['bar']
Der Wert zwischen den Klammern kann ein beliebiger Ausdruck sein. Wenn der Eigenschaftsname in einer Variablen gespeichert ist, müssen Sie daher die Klammernotation verwenden:
var foo = 'bar';
something[foo];
// both x = something[foo] and something[foo] = x work as expected
Das ist meine Lösung:
function resolve(path, obj) {
return path.split('.').reduce(function(prev, curr) {
return prev ? prev[curr] : null
}, obj || self)
}
Anwendungsbeispiele:
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 können wir zugreifen mit:
foo.bar
foo[someVar]
oderfoo["string"]
Der zweite Fall ermöglicht jedoch den dynamischen Zugriff auf Eigenschaften:
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
Im Folgenden finden Sie ein ES6-Beispiel dafür, wie Sie mit einem Eigenschaftsnamen, der durch Verketten von zwei Zeichenfolgen dynamisch generiert wurde, auf die Eigenschaft eines Objekts zugreifen können.
var suffix = " name";
var person = {
["first" + suffix]: "Nicholas",
["last" + suffix]: "Zakas"
};
console.log(person["first name"]); // "Nicholas"
console.log(person["last name"]); // "Zakas"
Dies wird als berechnete Eigenschaftsnamen bezeichnet
Sie können dies auf verschiedene Arten erreichen.
let foo = {
bar: 'Hello World'
};
foo.bar;
foo['bar'];
Die Klammernotation ist besonders leistungsfähig, da Sie auf eine Eigenschaft zugreifen können, die auf einer Variablen basiert:
let foo = {
bar: 'Hello World'
};
let prop = 'bar';
foo[prop];
Dies kann erweitert werden, um jede Eigenschaft eines Objekts zu durchlaufen. Dies kann aufgrund neuerer JavaScript-Konstrukte wie ... von ... überflüssig erscheinen, hilft jedoch bei der Veranschaulichung eines Anwendungsfalls:
let foo = {
bar: 'Hello World',
baz: 'How are you doing?',
last: 'Quite alright'
};
for (let prop in foo.getOwnPropertyNames()) {
console.log(foo[prop]);
}
Sowohl die Punkt- als auch die Klammernotation funktionieren erwartungsgemäß auch für verschachtelte Objekte:
let foo = {
bar: {
baz: 'Hello World'
}
};
foo.bar.baz;
foo['bar']['baz'];
foo.bar['baz'];
foo['bar'].baz;
Objektzerstörung
Wir könnten die Objektzerstörung auch als Mittel betrachten, um auf eine Eigenschaft in einem Objekt zuzugreifen, aber wie folgt:
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'
Sie können es so mit Lodash get machen
_.get(object, 'a[0].b.c');
Ich habe die folgenden Kommentare berücksichtigt und bin damit einverstanden. Eval ist zu vermeiden.
Der Zugriff auf Root-Eigenschaften in einem Objekt ist leicht zu erreichen obj[variable]
, aber das Verschachteln erschwert die Sache. Um nicht bereits geschriebenen Code zu schreiben, schlage ich vor, ihn zu verwenden lodash.get
.
Beispiel
// Accessing root property
var rootProp = 'rootPropert';
_.get(object, rootProp, defaultValue);
// Accessing nested property
var listOfNestedProperties = [var1, var2];
_.get(object, listOfNestedProperties);
Lodash get kann auf verschiedene Arten verwendet werden. Hier finden Sie einen Link zur Dokumentation lodash.get
eval
wenn immer möglich. stackoverflow.com/questions/86513/…
eval
für etwas so Triviales wie den Zugriff auf Immobilien ist einfach übertrieben und unter keinen Umständen ratsam. Was ist "Ärger"? obj['nested']['test']
funktioniert sehr gut und erfordert nicht, dass Sie Code in Zeichenfolgen einbetten.
obj['nested']['value']
- erinnere dich an Kinder, Eval ist böse!
_.get
an den Tisch bringen möchte . Ich denke, diese Antwort verdient jetzt positive Stimmen statt negative Stimmen. Es mag übertrieben sein, aber es ist gut zu wissen, dass es existiert.
Wann immer Sie dynamisch auf Eigenschaften zugreifen müssen, müssen Sie eine eckige Klammer verwenden, um auf Eigenschaften zuzugreifen, nicht auf "." Operator
Syntax: Objekt [Eigenschaft}
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])
Ich bin auf einen Fall gestoßen, in dem ich dachte, ich möchte die "Adresse" einer Objekteigenschaft als Daten an eine andere Funktion übergeben und das Objekt (mit AJAX) füllen, vom Adressarray nachschlagen und in dieser anderen Funktion anzeigen. Ich konnte die Punktnotation nicht verwenden, ohne String-Akrobatik zu betreiben, daher dachte ich, ein Array könnte stattdessen gut übergeben werden. Am Ende habe ich sowieso etwas anderes gemacht, schien aber mit diesem Beitrag verwandt zu sein.
Hier ist ein Beispiel eines Sprachdateiobjekts wie das, von dem ich Daten haben wollte:
const locs = {
"audioPlayer": {
"controls": {
"start": "start",
"stop": "stop"
},
"heading": "Use controls to start and stop audio."
}
}
Ich wollte in der Lage sein, ein Array wie das folgende zu übergeben: ["audioPlayer", "control", "stop"], um auf den Sprachtext zuzugreifen, in diesem Fall "stop".
Ich habe diese kleine Funktion erstellt, die den "am wenigsten spezifischen" (ersten) Adressparameter nachschlägt und das zurückgegebene Objekt sich selbst neu zuweist. Dann ist es bereit, den nächstspezifischeren Adressparameter nachzuschlagen, falls einer vorhanden ist.
function getText(selectionArray, obj) {
selectionArray.forEach(key => {
obj = obj[key];
});
return obj;
}
Verwendungszweck:
/* returns 'stop' */
console.log(getText(["audioPlayer", "controls", "stop"], locs));
/* returns 'use controls to start and stop audio.' */
console.log(getText(["audioPlayer", "heading"], locs));
Es wird interessant, wenn Sie auch Parameter an diese Funktion übergeben müssen.
Code 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
Dieser einfache Code kann nach tief verschachtelten Variablen / Werten suchen, ohne dass jede Variable auf dem Weg überprüft werden muss ...
var getValue = function( s, context ){
return Function.call( context || null, 'return ' + s )();
}
Ex. - eine tief verschachtelte Reihe von Objekten:
a = [
{
b : [
{
a : 1,
b : [
{
c : 1,
d : 2 // we want to check for this
}
]
}
]
}
]
Anstatt von :
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
Wir können jetzt:
if( getValue('a[0].b[0].b[0].d') == 2 ) // true
Prost!
Ich habe vor einiger Zeit eine Frage zu diesem Thema gestellt, und nach übermäßiger Recherche und dem Fehlen vieler Informationen, die hier sein sollten, habe ich das Gefühl, dass ich diesem älteren Beitrag etwas Wertvolles hinzufügen kann.
let properyValue = element.style['enter-a-property'];
Ich gehe diesen Weg jedoch selten, da er bei Eigenschaftswerten, die über Stylesheets zugewiesen wurden, nicht funktioniert. Um Ihnen ein Beispiel zu geben, werde ich mit ein bisschen Pseudocode demonstrieren.
let elem = document.getElementById('someDiv');
let cssProp = elem.style['width'];
Verwenden Sie das obige Codebeispiel. Wenn die width-Eigenschaft des div-Elements, das in der Variablen 'elem' gespeichert wurde, in einem CSS-Stylesheet und nicht in seinem HTML-Tag gestaltet wurde, erhalten Sie ohne Zweifel den Rückgabewert undefined, der darin gespeichert ist der Variablen cssProp. Der undefinierte Wert tritt auf, weil der in ein CSS-Stylesheet geschriebene Code berechnet werden muss, um den Wert zu erhalten, um den richtigen Wert zu erhalten. Sie müssen eine Methode verwenden, die den Wert der Eigenschaft berechnet, deren Wert im Stylesheet liegt.
function getCssProp(){
let ele = document.getElementById("test");
let cssProp = window.getComputedStyle(ele,null).getPropertyValue("width");
}
W3Schools getComputedValue Doc Dies ist ein gutes Beispiel, mit dem Sie spielen können. Dieser Link Mozilla CSS getComputedValue doc beschreibt jedoch ausführlich die Funktion getComputedValue und sollte von jedem aufstrebenden Entwickler gelesen werden, der sich mit diesem Thema nicht ganz auskennt.
$(selector).css(property,value)
... bekommt und setzt. Es ist das, was ich benutze. Der einzige Nachteil ist, dass Sie JQuery kennengelernt haben, aber dies ist ehrlich gesagt einer der vielen guten Gründe, warum jeder Javascript-Entwickler JQuery lernen sollte. Es macht das Leben einfach und bietet Methoden wie diese ist mit Standard-Javascript nicht verfügbar. Hoffe das hilft jemandem !!!
Für alle, die den Wert einer verschachtelten Variablen festlegen möchten, gehen Sie wie folgt vor:
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
Dokumentation: https://lodash.com/docs/4.17.15#set
Außerdem Dokumentation, wenn Sie einen Wert erhalten möchten: https://lodash.com/docs/4.17.15#get
Sie sollten verwenden JSON.parse
, werfen Sie einen Blick auf 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
ist bereits eine Zeichenfolge, `${foo}`
ist also genau das gleiche wie foo
. (Außerdem scheint Ihr Code einige zusätzliche Backslashes zu haben, die nicht dorthin gehören. Aber es wäre immer noch sinnlos, selbst wenn Sie diesen Syntaxfehler behoben hätten.)