918 Stimmen

Selbstreferenzen in Objektliteralen/Initialisierern

Gibt es eine Möglichkeit, so etwas wie das Folgende in JavaScript zum Laufen zu bringen?

var foo = {
    a: 5,
    b: 6,
    c: this.a + this.b  // Doesn't work
};

In der aktuellen Form führt dieser Code offensichtlich zu einem Referenzfehler, da this bezieht sich nicht auf foo . Aber ist Gibt es eine Möglichkeit, die Werte in den Eigenschaften eines Objektliterales von anderen, früher deklarierten Eigenschaften abhängig zu machen?

1018voto

Christian C. Salvadó Punkte 763569

Nun, das Einzige, was ich Ihnen sagen kann, sind getter :

var foo = {
  a: 5,
  b: 6,
  get c() {
    return this.a + this.b;
  }
}

console.log(foo.c) // 11

Dies ist eine syntaktische Erweiterung, die mit der ECMAScript-Spezifikation der 5. Auflage eingeführt wurde. Die Syntax wird von den meisten modernen Browsern (einschließlich IE9) unterstützt.

352voto

Felix Kling Punkte 751464

Sie könnten etwas wie folgt tun:

var foo = {
   a: 5,
   b: 6,
   init: function() {
       this.c = this.a + this.b;
       return this;
   }
}.init();

Dies wäre eine Art einmalige Initialisierung des Objekts.

Beachten Sie, dass Sie tatsächlich den Rückgabewert von init() まで foo deshalb müssen Sie return this .

228voto

T.J. Crowder Punkte 948310

Die offensichtliche, einfache Antwort fehlt, daher der Vollständigkeit halber:

Aber ist Gibt es eine Möglichkeit, die Werte in den Eigenschaften eines Objektliterales von anderen, früher deklarierten Eigenschaften abhängig zu machen?

Nein. Alle Lösungen hier verschieben es bis nach der Erstellung des Objekts (auf verschiedene Weise) und weisen dann die dritte Eigenschaft zu. Die einfachste Der beste Weg ist, dies einfach zu tun:

var foo = {
    a: 5,
    b: 6
};
foo.c = foo.a + foo.b;

Alle anderen sind nur indirektere Wege, um das Gleiche zu tun. (Die von Felix ist besonders clever, erfordert aber das Erstellen und Zerstören einer temporären Funktion, was die Komplexität erhöht; und hinterlässt entweder eine zusätzliche Eigenschaft auf dem Objekt oder [wenn Sie delete diese Eigenschaft] Auswirkungen auf die Leistung von nachfolgenden Eigenschaftszugriffen auf dieses Objekt).

Wenn Sie alles innerhalb eines Ausdrucks benötigen, können Sie das auch ohne die temporäre Eigenschaft tun:

var foo = function(o) {
    o.c = o.a + o.b;
    return o;
}({a: 5, b: 6});

Oder natürlich, wenn Sie dies mehr als einmal tun müssen:

function buildFoo(a, b) {
    var o = {a: a, b: b};
    o.c = o.a + o.b;
    return o;
}

dann dort, wo Sie es brauchen:

var foo = buildFoo(5, 6);

71voto

zzzzBov Punkte 166065

Instanzieren Sie einfach eine anonyme Funktion:

var foo = new function () {
    this.a = 5;
    this.b = 6;
    this.c = this.a + this.b;
};

42voto

voscausa Punkte 10531

In ES6 können Sie jetzt "lazy cached"-Eigenschaften erstellen. Bei der ersten Verwendung wird die Eigenschaft einmal ausgewertet und zu einer normalen statischen Eigenschaft. Ergebnis: Beim zweiten Mal wird der Overhead der mathematischen Funktion übersprungen.

Der Zauber liegt im Getter.

const foo = {
    a: 5,
    b: 6,
    get c() {
        delete this.c;
        return this.c = this.a + this.b
    }
};

Im Pfeil-Getter this hebt die umgebende lexikalische Reichweite .

foo     // {a: 5, b: 6}
foo.c   // 11
foo     // {a: 5, b: 6 , c: 11}

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X