Zugriff auf eine Objekteigenschaft mit einem dynamisch berechneten Namen

Lesezeit: 6 Minuten

Benutzeravatar von RichW
RichW

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!"

  • Siehe auch Eigenschaftszugriff: Punktnotation vs. Klammern? und Wie füge ich einem Objekt eine Eigenschaft hinzu, indem ich eine Variable als Namen verwende?

    – Bergi

    18. November 2014 um 6:11 Uhr

Benutzeravatar von Jan Hančič
Jan Hancic

Es gibt zwei Möglichkeiten, auf Eigenschaften zuzugreifen eines Objekts:

  • Punktnotation: something.bar
  • Klammernotation: 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 something = {
  bar: 'foo'
};
var foo = 'bar';

// both x = something[foo] and something[foo] = x work as expected
console.log(something[foo]);
console.log(something.bar)

  • Seien Sie vorsichtig damit: Javascript-Compiler werden hier Fehler machen, da sie keine Zeichenfolgen umbenennen, aber Objekteigenschaften umbenennen

    – chacham15

    6. Dezember 2011 um 8:40 Uhr

  • Einige weitere Informationen darüber, warum dies möglich ist: JS-Objekte sind assoziative Arrays, deshalb. Weiterführende Literatur: quirksmode.org/js/associative.html stackoverflow.com/questions/14031368/…

    – Sudhanshu Mishra

    3. Juni 2014 um 9:00 Uhr

  • @dotnetguy Nein, das sind sie nicht. Arrays sind Objekte, die vom einfachen JS-Objektprototypen erben, und daher können Sie Eigenschaften wie bei jedem einfachen Objekt im Handumdrehen hinzufügen. Das ‘assoziative’ Verhalten ist eher objektartig als Array-artig. Sie können die „assoziative“ Version nicht durch einen einfachen Index iterieren, sodass sie kein Array-ähnliches Verhalten zeigt. Sie können Ihr ‘assoziatives’ Array als {} oder definieren [] und behandeln sie in beiden Fällen gleich, soweit es um den wahlfreien Zugriff auf Eigentum geht.

    – Besiegter Wombat

    3. Januar 2017 um 16:01 Uhr

  • @VanquishedWombat Sie sind sich nicht sicher, worauf sich Ihr Einwand bezieht? Ich habe nicht gesagt, dass JS-Objekte Arrays sind?

    – Sudhanshu Mishra

    6. Januar 2017 um 0:30 Uhr

  • Bitte verzichten Sie in Zukunft auf die Verwendung von foo-bar … Diese Erklärung ist so verschleiert.

    – Cornelius

    25. Januar um 3:33

Benutzeravatar von abahet
abahet

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'})

  • Hervorragende Antwort, siehe auch: stackoverflow.com/questions/37510640/…

    – Julian Ritter

    3. Januar 2019 um 13:45 Uhr

  • Sie haben mich dazu inspiriert, eine erweiterte Version zu erstellen, die die Notation von Klammern und Eigenschaftsnamen mit Leerzeichen sowie die Validierung der Eingaben ermöglicht: it.knightnet.org.uk/kb/node-js/get-properties

    – Julian Ritter

    3. Januar 2019 um 14:04 Uhr

  • Ich liebe diese Lösung. Ich versuche jedoch, die Werte im ursprünglichen Objekt zu ändern, es scheint, dass Ihre Funktion eine Unterkopie des Objekts zurückgibt. Ist es möglich, es so zu ändern, dass das Ändern des zurückgegebenen Objekts das Original ändert?

    – Adler1

    28. Februar 2020 um 17:39 Uhr

  • Ich würde auch gerne die “Set Value” -Version davon sehen.

    – GaryO

    21. August 2020 um 21:05 Uhr

  • Gute Antwort! Es funktioniert für tief verschachtelte Eigenschaften.

    – NeNaD

    21. Januar um 14:56 Uhr

In Javascript können wir zugreifen mit:

  • Punktnotation – foo.bar
  • eckige Klammern – foo[someVar] oder foo["string"]

Aber nur der zweite Fall erlaubt 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

  • Ich starre auf 2.000 Zeilen mit if-Anweisungen, weil der vorherige Entwickler keine eckigen Klammern verwendet und statisch auf Objekteigenschaften durch Punktnotation zugegriffen hat. Es handelt sich um eine Genehmigungsprozess-App mit 7 verschiedenen Genehmigern, und die Schritte sind alle gleich. /Ruhe in Frieden

    – Tschad

    7. Juni 2018 um 14:28 Uhr


Benutzeravatar von zloctb
zloctb

Im Folgenden finden Sie ein ES6-Beispiel, wie Sie auf die Eigenschaft eines Objekts zugreifen können, indem Sie einen Eigenschaftsnamen verwenden, der dynamisch durch Verketten zweier Zeichenfolgen generiert wurde.

var suffix = " name";

var person = {
    ["first" + suffix]: "Nicholas",
    ["last" + suffix]: "Zakas"
};

console.log(person["first name"]);      // "Nicholas"
console.log(person["last name"]);       // "Zakas"

Das nennt man berechnete Eigenschaftsnamen

Benutzeravatar von Gorka Hernandez
Gorka Hernández

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 damit 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 for … of … überflüssig erscheinen, hilft aber 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 auch wie erwartet für verschachtelte Objekte:

let foo = {
    bar: {
        baz: 'Hello World'
    }
};

foo.bar.baz;
foo['bar']['baz'];
foo.bar['baz'];
foo['bar'].baz;

Objektdestrukturierung

Wir könnten die Objektdestrukturierung auch als Mittel zum Zugriff auf eine Eigenschaft in einem Objekt betrachten, 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"

Benutzeravatar von JJJ
JJJ

Sie können dies mit Lodash get tun

_.get(object, 'a[0].b.c');

AKTUALISIERT

Der Zugriff auf Root-Eigenschaften in einem Objekt ist einfach mit möglich obj[variable], aber verschachtelt zu werden, verkompliziert die Dinge. Um keinen 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, die Dokumentation lodash.get

  • Es ist am besten, die Verwendung zu vermeiden eval wenn möglich. stackoverflow.com/questions/86513/…

    – Lukas

    23. Juni 2015 um 18:07 Uhr

  • Verwenden eval denn etwas so Triviales wie der Zugriff auf Eigenschaften 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.

    – Kyll

    23. Oktober 2015 um 10:14 Uhr

  • eval ist dreimal langsamer oder mehr, ich würde dies Neulingen nicht empfehlen, weil es ihnen schlechte Gewohnheiten beibringen könnte. ich benutze obj['nested']['value'] – Denken Sie daran, Kinder, Evaluieren ist böse!

    – zackig weich

    26. November 2015 um 1:25 Uhr


  • @Luke Er ist jetzt der einzige, der Lodash bringen will _.get zum Tisch. Ich denke, diese Antwort verdient jetzt Upvotes statt Downvotes. Es mag übertrieben sein, aber es ist gut zu wissen, dass es existiert.

    – Emil Bergeron

    20. Dezember 2016 um 21:42 Uhr

  • Vielen Dank, dass Sie Lodash dafür eingeführt haben. Ich bin von Google hierher gekommen, um nach einer Methode zu suchen, um einen Wert tief in einem Objekt zu setzen, und habe ihre _.set-Methode verwendet (die mit der oben identisch ist, aber mit dem zusätzlichen Argument für den zu setzenden Wert).

    – TPHughes

    3. Juli 2018 um 9:03 Uhr

1436680cookie-checkZugriff auf eine Objekteigenschaft mit einem dynamisch berechneten Namen

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy