¿Cómo utilizar una variable para una clave en un objeto literal de JavaScript?

Resuelto speendo asked hace 14 años • 16 respuestas

¿Por qué funciona lo siguiente?

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

Mientras que esto no funciona:

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

Para hacerlo aún más claro: por el momento no puedo pasar una propiedad CSS a la función animada como variable.

speendo avatar Feb 16 '10 23:02 speendo
Aceptado

{ thetop : 10 }es un objeto literal válido. El código creará un objeto con una propiedad denominada thetopque tiene un valor de 10. Los dos siguientes son iguales:

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

En ES5 y versiones anteriores, no se puede utilizar una variable como 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 define ComputedPropertyName como parte de la gramática para literales de objetos, lo que le permite escribir el código de esta manera:

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

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

Puede utilizar esta nueva sintaxis en las últimas versiones de cada navegador convencional.

Andy E avatar Feb 16 '2010 16:02 Andy E

Con ECMAScript 2015 ahora puedes hacerlo directamente en la declaración de objeto con la notación entre corchetes: 

var obj = {
  [key]: value
}

Donde keypuede haber cualquier tipo de expresión (por ejemplo, una variable) que devuelva un valor.

Entonces aquí tu código se vería así:

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

Donde thetopserá evaluado antes de ser utilizado como clave.

kube avatar Mar 15 '2016 23:03 kube

Cita de ES5 que dice que no debería funcionar

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

Especificación: http://www.ecma-international.org/ecma-262/5.1/#sec-11.1.5

Nombre de la propiedad :

  • Nombre del identificador
  • Literal de cadena
  • NuméricoLiteral

[...]

La producción PropertyName: IdentifierName se evalúa de la siguiente manera:

  1. Devuelve el valor de cadena que contiene la misma secuencia de caracteres que el nombre del identificador.

La producción PropertyName: StringLiteral se evalúa de la siguiente manera:

  1. Devuelve el SV [valor de cadena] de StringLiteral.

La producción PropertyName: NumericLiteral se evalúa de la siguiente manera:

  1. Sea nbr el resultado de formar el valor de NumericLiteral.
  2. Volver a cadena (núm.).

Esto significa que:

  • { theTop : 10 }es exactamente igual que{ 'theTop' : 10 }

    Es PropertyName theTopun IdentifierName, por lo que se convierte al 'theTop'valor de cadena, que es el valor de cadena de 'theTop'.

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

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