¿Cómo creo una clave dinámica para agregarla a una variable de objeto de JavaScript?
Estoy intentando algo como esto, pero este ejemplo no funciona.
jsObj = {};
for (var i = 1; i <= 10; i++) {
jsObj{'key' + i} = 'example ' + 1;
}
¿Qué puedo hacer para crear una clave dinámica como esta?
Respuesta #1
Corchetes:
jsObj['key' + i] = 'example' + 1;
En JavaScript, todos los arreglos son objetos, pero no todos los objetos son arreglos. La principal diferencia (y una que es bastante difícil de imitar con JavaScript puro y objetos simples) es que las instancias de arreglos mantienen la propiedad length de manera que refleja uno más el valor numérico de la propiedad cuyo nombre es numérico y cuyo valor, al convertirse en número, es el mayor de todas esas propiedades. Eso suena realmente extraño, pero simplemente significa que dada una instancia de arreglo, las propiedades con nombres como "0", "5", "207", y así sucesivamente, son tratadas de manera especial en que su existencia determina el valor de length. Y, además de eso, el valor de length se puede establecer para eliminar dichas propiedades. Establecer el length de un arreglo en 0 efectivamente elimina todas las propiedades cuyos nombres parecen números enteros.
OK, entonces eso es lo que hace que un arreglo sea especial. Todo eso, sin embargo, no tiene nada que ver con cómo funciona el operador [ ] en JavaScript. Ese operador es un mecanismo de acceso a propiedades de objetos que funciona con cualquier objeto. Es importante notar en ese sentido que los nombres de propiedades numéricas de un arreglo no son especiales en lo que respecta al acceso simple a propiedades. Son solo cadenas que por casualidad parecen números, pero los nombres de propiedades en objetos de JavaScript pueden ser cualquier tipo de cadena que desees.
Así, la forma en que el operador [ ] funciona en un bucle for que itera a través de un arreglo:
for (var i = 0; i < myArray.length; ++i) {
var value = myArray[i]; // property access
// ...
}
realmente no es diferente de la forma en que [ ] funciona al acceder a una propiedad cuyo nombre es alguna cadena computada:
var value = jsObj["key" + i];
El operador [ ] allí está haciendo precisamente lo mismo en ambos casos. El hecho de que en un caso el objeto involucrado sea un arreglo es irrelevante, en otras palabras.
Cuando estableces valores de propiedades usando [ ], la historia es la misma excepto por el comportamiento especial relacionado con mantener la propiedad length. Si estableces una propiedad con una clave numérica en una instancia de arreglo:
myArray[200] = 5;
entonces (suponiendo que "200" sea el nombre de propiedad numérica más grande) la propiedad length se actualizará a 201 como un efecto secundario de la asignación de la propiedad. Sin embargo, si se hace lo mismo con un objeto simple:
myObj[200] = 5;
No hay tal efecto secundario. La propiedad llamada "200" tanto del array como del objeto se establecerá en el valor 5 de la misma manera exacta en otros aspectos.
Uno podría pensar que debido a que ese comportamiento de length es bastante útil, bien podrías hacer que todos los objetos sean instancias del constructor Array en lugar de objetos simples. No hay nada directamente incorrecto en eso (aunque puede ser confuso, especialmente para personas familiarizadas con algunos otros lenguajes, que algunas propiedades se incluyan en length pero otras no). Sin embargo, si estás trabajando con la serialización JSON (algo bastante común), entiende que las instancias de array se serializan a JSON de una manera que solo involucra las propiedades con nombre numérico. Otras propiedades agregadas al array nunca aparecerán en la forma JSON serializada. Por ejemplo:
var obj = [];
obj[0] = "hello world";
obj["something"] = 5000;
var objJSON = JSON.stringify(obj);
el valor de "objJSON" será una cadena que contiene únicamente ["hello world"]; la propiedad "something" se perderá.
ES2015:
Si puedes usar las características de JavaScript ES6, puedes usar Nombres de Propiedades Computadas para manejar esto muy fácilmente:
var key = 'DYNAMIC_KEY',
obj = {
[key]: 'ES6!'
};
console.log(obj);
// > { 'DYNAMIC_KEY': 'ES6!' }
