¿Cómo utilizar una variable para una clave en un objeto literal de JavaScript?
¿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.
{ thetop : 10 }
es un objeto literal válido. El código creará un objeto con una propiedad denominada thetop
que 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.
Con ECMAScript 2015 ahora puedes hacerlo directamente en la declaración de objeto con la notación entre corchetes:
var obj = {
[key]: value
}
Donde key
puede 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 thetop
será evaluado antes de ser utilizado como clave.
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:
- 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:
- Devuelve el SV [valor de cadena] de StringLiteral.
La producción PropertyName: NumericLiteral se evalúa de la siguiente manera:
- Sea nbr el resultado de formar el valor de NumericLiteral.
- Volver a cadena (núm.).
Esto significa que:
{ theTop : 10 }
es exactamente igual que{ 'theTop' : 10 }
Es
PropertyName
theTop
unIdentifierName
, 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),StringLiteral
yNumericLiteral
(también se expande a una cadena).