2010-02-16 8 views
228

¿Por qué funciona lo siguiente?Usar una variable para una clave en un objeto de JavaScript literal

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

Mientras que esto no funciona:

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

para que sea aún más clara: Por el momento no soy capaz de pasar una propiedad CSS a la función animado como una variable.

+1

vea también: [crear objetos utilizando las variables de nombre de la propiedad] (http://stackoverflow.com/q/3153969/1048572) – Bergi

+1

consulta : [creación de objetos con teclas dinámicas] (http://stackoverflow.com/q/19837916/1048572) – Bergi

Respuesta

407

{ thetop : 10 } es un objeto literal válido. El código se crea un objeto con una propiedad denominada thetop que tiene un valor de 10. Tanto los siguientes son los mismos:

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

En ES5 y anteriores, no se puede utilizar una variable como un nombre de propiedad dentro de un objeto literal . Su única opción es hacer lo siguiente:

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 como parte de la gramática para los literales de objetos, lo que le permite escribir el código como el siguiente:

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

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

Usted puede utilizar esta nueva sintaxis en las últimas versiones de cada navegador mainstream.

+0

¡Entiendo! ¡Gracias! ¿Esto no funciona también con eval? Quiero decir que no funciona en mi ejemplo en este momento, pero creo que debería ... :-) – speendo

+2

@Marcel: 'eval()' no funcionaría dentro de un objeto literal para nombres de propiedad dinámicos, usted ' Acabo de recibir un error. No solo eso, sino 'eval()' realmente no debería usarse para tales cosas. Hay un excelente artículo sobre el uso correcto e incorrecto de 'eval': http://blogs.msdn.com/ericlippert/archive/2003/11/01/53329.aspx –

+1

@AndyE considere actualizar" versiones recientes "y" IE actual " TP "con un tiempo más específico como" Versiones posteriores a XXX "o" después de 2014-mm "(yo haría el cambio yo mismo, pero no sé qué buenos valores serían. –

3

he utilizado lo siguiente para agregar una propiedad con un nombre "dinámico" a un objeto:

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

key es el nombre de la nueva propiedad.

El objeto de propiedades pasaron a animate será {left: 20, width: 100, top: 10}

Esto es sólo con la notación necesaria [] según lo recomendado por las otras respuestas, pero con menos líneas de código!

6

ES5 cita que dice que no debería funcionar

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

PropertyName:

  • IdentifierName
  • StringLiteral
  • NumericLiteral

[...]

El PropertyName producción: IdentifierName se evalúa como sigue:

  1. Return el valor de cadena que contiene la misma secuencia de caracteres como el IdentifierName.

El PropertyName producción: StringLiteral se evalúa como sigue:

  1. Return el [valor String] SV de la StringLiteral.

El PropertyName producción: NumericLiteral se evalúa como sigue:

  1. Vamos NBR ser el resultado de la formación del valor de la NumericLiteral.
  2. Return ToString (nbr).

Esto significa que:

  • { theTop : 10 } es exactamente el mismo que { 'theTop' : 10 }

    El PropertyNametheTop es un IdentifierName, por lo que se convierte en el valor 'theTop' cadena, que es la valor de cadena de 'theTop'.

  • No es posible escribir inicializadores de objetos (literales) con teclas variables.

    Las únicas tres opciones son IdentifierName (se expande a cadena literal), StringLiteral y NumericLiteral (también se expande a una cadena).

reglas han cambiado para ES6: https://stackoverflow.com/a/2274327/895245

+2

Downvoters: Fui el * primero * para citar cualquier estándar en esta pregunta. La cita de ES6 en la respuesta superior fue editada * después * Respondí, y ese estándar aún no se aceptó en el En caso de que sepas por qué más recibo los votos a favor, explícalo, solo quiero aprender. Debo obtener la insignia de presión de los pares ... –

+0

Supongo s la votación negativa se debió principalmente a que su respuesta no ofrece una solución, y "no es útil" en ese sentido. Votando hacia la presión de grupo :-) – Bergi

+2

@Bergi ¡gracias por tener el coraje! :-) Pero creo que he respondido la pregunta * directamente *: P: "¿Por qué funciona lo siguiente?". A: porque ES5 lo dice. "¿Qué hacer al respecto?" está implícito ¿Descartó la pregunta principal por decir "Es imposible" * sin una cita estándar * antes de que alguien editara la solución ES6? –

67

Con ECMAScript 2015 que ahora son capaces de hacerlo directamente en la declaración de objeto con los soportes de la notación:  

var obj = { 
    [key]: value 
} 

Dónde key puede ser cualquier clase de expresión (por ejemplo, una variable) que devuelve un valor.

Así que aquí el código se vería así:

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

Dónde thetop será reemplazado por el valor de la variable.

2

Añadir un corchete alrededor de la variable funciona bien para mí. Prueba este código dado

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

Esto no funcionará en las versiones anteriores de EcmaScript, pero hoy en día este es un enfoque muy limpio. – Oliver

0

:

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

Traducción:

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

Como se puede ver, la declaración { thetop : 10 } no hace uso de la variable thetop. En su lugar, crea un objeto con una clave llamada thetop.Si desea que la clave sea el valor de la variable thetop, entonces usted tendrá que usar corchetes thetop:

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

La sintaxis de corchetes se ha introducido con ES6. En versiones anteriores de JavaScript, que tendría que hacer lo siguiente:

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