literales - recorrer array de objetos javascript
¿Cómo usar una variable para una clave en un objeto literal de JavaScript? (9)
¿Por qué funciona lo siguiente?
<something>.stop().animate(
{ ''top'' : 10 }, 10
);
Considerando que esto no funciona:
var thetop = ''top'';
<something>.stop().animate(
{ thetop : 10 }, 10
);
Para que sea aún más claro: en este momento no puedo pasar una propiedad CSS a la función animada como una variable.
Agregar corchete alrededor de la variable funciona bien para mí. Prueba esto
var thetop = ''top'';
<something>.stop().animate(
{ [thetop] : 10 }, 10
);
Código dado:
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 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 tendrá que usar corchetes alrededor de la parte thetop
:
var thetop = ''top'';
var config = { [thetop] : 10 }; // config.top = 10
<something>.stop().animate(config, 10);
La sintaxis de corchete se ha introducido con ES6. En versiones anteriores de JavaScript, tendría que hacer lo siguiente:
var thetop = ''top'';
var config = (
obj = {},
obj['''' + thetop] = 10,
obj
); // config.top = 10
<something>.stop().animate(config, 10);
Con ECMAScript 2015 ahora puede hacerlo directamente en la declaración de objetos con la notación de corchetes:
var obj = {
[key]: value
}
Donde key
puede ser cualquier tipo de expresión (por ejemplo, una variable) que devuelve un valor.
Así que aquí su código se vería así:
<something>.stop().animate({
[thetop]: 10
}, 10)
Donde el thetop
será reemplazado por el valor variable.
De esta manera también se puede lograr la salida deseada.
var jsonobj={};
var count=0;
$(document).on(''click'',''#btnadd'', function() {
jsonobj[count]=new Array({ "1" : $("#txtone").val()},{ "2" : $("#txttwo").val()});
count++;
console.clear();
console.log(jsonobj);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<span>value 1</span><input id="txtone" type="text"/>
<span>value 2</span><input id="txttwo" type="text"/>
<button id="btnadd">Add</button>
He usado 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 las propiedades pasadas a animate
será {left: 20, width: 100, top: 10}
Esto es solo usando la notación requerida []
como lo recomiendan las otras respuestas, ¡pero con menos líneas de código!
La implementación de ES5 para asignar claves está abajo:
var obj = Object.create(null),
objArgs = (
(objArgs = {}),
(objArgs.someKey = {
value: ''someValue''
}), objArgs);
Object.defineProperties(obj, objArgs);
He adjuntado un fragmento que solía convertir a objeto desnudo.
var obj = {
''key1'': ''value1'',
''key2'': ''value2'',
''key3'': [
''value3'',
''value4'',
],
''key4'': {
''key5'': ''value5''
}
}
var bareObj = function(obj) {
var objArgs,
bareObj = Object.create(null);
Object.entries(obj).forEach(function([key, value]) {
var objArgs = (
(objArgs = {}),
(objArgs[key] = {
value: value
}), objArgs);
Object.defineProperties(bareObj, objArgs);
});
return {
input: obj,
output: bareObj
};
}(obj);
if (!Object.entries) {
Object.entries = function(obj){
var arr = [];
Object.keys(obj).forEach(function(key){
arr.push([key, obj[key]]);
});
return arr;
}
}
console(bareObj);
Podrías hacer lo siguiente para ES5:
var theTop = ''top''
<something>.stop().animate(
JSON.parse(''{"'' + theTop + ''":'' + JSON.stringify(10) + ''}''), 10
)
O extraer a una función:
function newObj (key, value) {
return JSON.parse(''{"'' + key + ''":'' + JSON.stringify(value) + ''}'')
}
var theTop = ''top''
<something>.stop().animate(
newObj(theTop, 10), 10
)
{ thetop : 10 }
es un objeto literal válido. El código creará un objeto con una propiedad llamada thetop
que tiene un valor de 10. Los dos siguientes son los mismos:
obj = { thetop : 10 };
obj = { "thetop" : 10 };
En ES5 y versiones anteriores, no puede usar una variable como nombre de propiedad dentro de un objeto literal. Tu ú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 defines 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 general.
ES5 cita que dice que no debería funcionar
Especificación: http://www.ecma-international.org/ecma-262/5.1/#sec-11.1.5
Nombre de la propiedad :
- Nombre del identificador
- StringLiteral
- Numérico literal
[...]
La propiedad PropertyName: IdentifierName se evalúa de la siguiente manera:
- Devuelve el valor de cadena que contiene la misma secuencia de caracteres que el nombre de identificador.
La propiedad PropertyName: StringLiteral se evalúa de la siguiente manera:
- Devuelve el SV [valor de cadena] de StringLiteral.
La propiedad PropertyName: NumericLiteral se evalúa de la siguiente manera:
- Sea nbr el resultado de formar el valor de NumericLiteral.
- Vuelve a ToString (nbr).
Esto significa que:
{ theTop : 10 }
es exactamente igual que{ ''theTop'' : 10 }
PropertyName
theTop
es unIdentifierName
, por lo que se convierte al valor de cadena''theTop''
, 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 cadena literal),StringLiteral
yNumericLiteral
(también se expande a una cadena).
Las reglas han cambiado para ES6: https://.com/a/2274327/895245