2010-02-16 9 views
228

Warum funktioniert Folgendes?Verwenden einer Variablen für einen Schlüssel in einem JavaScript-Objektliteral

<something>.stop().animate(
    { 'top' : 10 }, 10 
); 

Während dies nicht funktioniert:

var thetop = 'top'; 
<something>.stop().animate(
    { thetop : 10 }, 10 
); 

Um es noch deutlicher zu machen: Im Moment ist mir nicht in der Lage eine CSS-Eigenschaft auf die belebten Funktion als Variable zu übergeben.

+1

: In früheren Versionen von JavaScript, würden Sie Folgendes zu tun haben [erstellen Objektvariablen für Eigenschaftsnamen verwenden] (http://stackoverflow.com/q/3153969/1048572) – Bergi

+1

siehe auch : [Erstellen von Objekten mit dynamischen Schlüsseln] (http://stackoverflow.com/q/19837916/1048572) – Bergi

Antwort

407

{ thetop : 10 } ist ein gültiges Objektliteral. Der Code wird ein Objekt mit einer Eigenschaft namens thetop erstellen, die einen Wert von 10. Sowohl die folgenden sind auch hat:

obj = { thetop : 10 }; 
obj = { "thetop" : 10 }; 

In ES5 und früher Sie eine Variable nicht als Eigenschaftsnamen innerhalb eines Objektliteral verwenden können . Ihre einzige Option ist folgendes zu tun:

var thetop = "top"; 

// create the object literal 
var aniArgs = {}; 

// Assign the variable property name with a value of 10 
aniArgs[thetop] = 10; 

// Pass the resulting object to the animate method 
<something>.stop().animate(
    aniArgs, 10 
); 

ES6 definesComputedPropertyName als Teil der Grammatik für Objektliterale, die Sie den Code wie folgt schreiben können:

var thetop = "top", 
    obj = { [thetop]: 10 }; 

console.log(obj.top); // -> 10 

Sie verwenden Diese neue Syntax in den neuesten Versionen jedes Mainstream-Browsers.

+0

Ich verstehe! Vielen Dank! Shoudln't das funktioniert auch mit eval? Ich meine es funktioniert in meinem Beispiel im Moment nicht, aber ich verdünne es sollte ... :-) – speendo

+2

@Marcel: 'eval()' würde nicht funktionieren in einem Objektliteral für dynamische Eigenschaftsnamen, du ' Ich bekomme nur einen Fehler. Nicht nur das, aber 'eval()' sollte wirklich nicht für solche Dinge verwendet werden. Es gibt einen ausgezeichneten Artikel über die korrekte und inkorrekte Verwendung von 'eval': http://blogs.msdn.com/ericlippert/archive/2003/11/01/53329.aspx –

+1

@AndyE in Betracht ziehen," neuere Versionen "und" aktuelles IE TP "mit etwas spezifischerer Zeit wie" Versionen später als XXX "oder" nach 2014-mm "(Ich würde selbst Änderungen vornehmen, aber ich weiß nicht, welche guten Werte es geben würde. –

3

Ich habe folgende hinzufügen, um eine Eigenschaft mit einem „dynamischen“ Namen für ein Objekt verwendet:

var key = 'top'; 
$('#myElement').animate(
    (function(o) { o[key]=10; return o;})({left: 20, width: 100}), 
    10 
); 

key ist der Name der neuen Eigenschaft.

Das Objekt der Eigenschaften zu animate weitergegeben wird {left: 20, width: 100, top: 10}

sein Dies ist nur mit der erforderlichen [] Notation wie die anderen Antworten zu empfehlen, aber mit weniger Codezeilen!

6

ES5 Zitat, das sagt, dass es nicht

Spec funktionieren sollte: http://www.ecma-international.org/ecma-262/5.1/#sec-11.1.5

Property:

  • IdentifierName
  • Zeichenketten-Literale
  • NumericLiteral

[...]

Die Produktion Property: IdentifierName wird wie folgt bewertet:

  1. Return der String-Wert die gleiche Abfolge von Zeichen, die als IdentifierName enthält.

Die Produktion Property: Zeichenketten-Literale wird wie folgt bewertet:

  1. Return den SV [Zeichenfolge] der Zeichenketten-Literale.

Die Produktion Property: NumericLiteral wird wie folgt bewertet:

  1. nbr das Ergebnis ließ den Wert der NumericLiteral bilden.
  2. Rückgabe ToString (nbr). Diese

bedeutet:

  • { theTop : 10 } genau die gleiche wie { 'theTop' : 10 }

    ist Das PropertyNametheTop ein IdentifierName ist, so dass es an den 'theTop' Stringwert konvertiert wird, die den IS Zeichenfolgenwert von 'theTop'.

  • Es ist nicht möglich, Objektinitialisierungen (Literale) mit variablen Schlüsseln zu schreiben.

    Die einzigen drei Optionen sind IdentifierName (expandiert in String-Literal), StringLiteral und NumericLiteral (wird auch zu einer Zeichenfolge erweitert).

Regeln haben für ES6 geändert: https://stackoverflow.com/a/2274327/895245

+2

Downwoters: Ich war der * erste * zu irgendeinem Standard zu dieser Frage zu zitieren.Das ES6 Zitat auf der obersten Antwort wurde bearbeitet * nach * Ich antwortete, und dieser Standard wurde noch nicht akzeptiert bei der Wenn du zufällig weißt, warum ich sonst noch eine Bewertung bekomme, bitte, erkläre, ich will nur lernen, ich könnte genauso gut das Gruppendruck-Abzeichen bekommen ... –

+0

Ich glaube Der Grund dafür war, dass Ihre Antwort keine Lösung bietet und in dieser Hinsicht "nicht nützlich" ist. Abstimmung auf Gruppendruck :-) – Bergi

+2

@Bergi danke für den Mut! :-) Aber ich denke, ich habe die Frage * direkt * beantwortet: Q: "Warum funktioniert folgendes?". A: weil ES5 das sagt. "Was ist damit zu tun?" ist implizit. Haben Sie die Top-Frage abgelehnt, weil Sie gesagt haben "Es ist unmöglich" * ohne ein Standardzitat *, bevor jemand in der ES6-Lösung bearbeitet hat? –

67

Mit ECMAScript 2015 Sie sind nun in der Lage direkt in Objektdeklaration mit den Klammern Notation zu tun:  

var obj = { 
    [key]: value 
} 

Wo key jede Art sein kann Ausdruck (zB eine Variable) einen Wert zurückgeben.

Also hier würde der Code wie folgt aussehen:

<something>.stop().animate({ 
    [thetop]: 10 
}, 10) 

Wo thetop durch den Variablenwert ersetzt werden.

2

Hinzufügen von eckigen Klammer um die Variable funktioniert gut für mich. Versuchen Sie, diese

var thetop = 'top'; 
<something>.stop().animate(
    { [thetop] : 10 }, 10 
); 
+0

Dies funktioniert nicht in älteren Versionen von EcmaScript, aber heutzutage ist dies ein sehr sauberer Ansatz. – Oliver

0

Gegeben Code:

var thetop = 'top'; 
<something>.stop().animate(
    { thetop : 10 }, 10 
); 

Übersetzung:

var thetop = 'top'; 
var config = { thetop : 10 }; // config.thetop = 10 
<something>.stop().animate(config, 10); 

Wie Sie sehen können, die { thetop : 10 } Erklärung nicht die Verwendung der Variablen thetop machen. Stattdessen erstellt es ein Objekt mit einem Schlüssel mit dem Namen thetop.

var thetop = 'top'; 
var config = { [thetop] : 10 }; // config.top = 10 
<something>.stop().animate(config, 10); 

Die eckige Klammer-Syntax wurde mit ES6 eingeführt: Wenn Sie die Taste kann der Wert der Variablen thetop wollen, dann werden Sie eckige Klammern um thetop zu verwenden. siehe auch

var thetop = 'top'; 
var config = (
    obj = {}, 
    obj['' + thetop] = 10, 
    obj 
); // config.top = 10 
<something>.stop().animate(config, 10); 
Verwandte Themen