Comment utiliser une variable pour une clé dans un objet JavaScript littérale?
pourquoi ce qui suit fonctionne?
<something>.stop().animate(
{ 'top' : 10 }, 10
);
attendu que cela ne fonctionne pas:
var thetop = 'top';
<something>.stop().animate(
{ thetop : 10 }, 10
);
pour le rendre encore plus clair: pour le moment je ne suis pas en mesure de passer une propriété CSS à la fonction animate en tant que variable.
8 réponses
{ thetop : 10 }
est un objet littéral valide. Le code créera un objet avec une propriété nommée thetop
qui a une valeur de 10. Les deux sont identiques:
obj = { thetop : 10 };
obj = { "thetop" : 10 };
dans ES5 et avant, vous ne pouvez pas utiliser une variable comme nom de propriété dans un objet littéral. Votre seule option est de faire ce qui suit:
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 définit ComputedPropertyName dans le cadre de la grammaire pour les littérales objet, qui vous permet d'écrire le code comme ceci:
var thetop = "top",
obj = { [thetop]: 10 };
console.log(obj.top); // -> 10
Vous pouvez utiliser cette nouvelle syntaxe dans les dernières versions de chaque intégrer navigateur.
avec ECMAScript 2015 vous pouvez maintenant le faire directement dans la déclaration d'objet avec la notation entre parenthèses:
var obj = {
[key]: value
}
où key
peut être n'importe quelle sorte d'expression (par exemple une variable) retournant une valeur.
alors voici votre code ressemblerait à:
<something>.stop().animate({
[thetop]: 10
}, 10)
où thetop
sera remplacé par la valeur variable.
ES5 citation qui dit qu'il ne devrait pas travailler
Spec: http://www.ecma-international.org/ecma-262/5.1/#sec-11.1.5
PropertyName :
- identifiant-nom
- StringLiteral
- NumericLiteral
[...]
Le nom propre de production: IdentifierName est évalué comme suit:
- renvoie la valeur de chaîne contenant la même séquence de caractères que le nom D'identification.
le nom propre de la production : StringLiteral est évalué comme suit:
- renvoie la valeur SV [String] du StringLiteral.
le nom propre de la production : NumericLiteral est évalué comme suit:
- Laissez-nbr être le résultat de la formation de la valeur de la NumericLiteral.
- Retour ToString(nbr).
cela signifie que:
-
{ theTop : 10 }
est le même que{ 'theTop' : 10 }
le
PropertyName
theTop
est unIdentifierName
, il est donc converti en'theTop'
chaîne de valeur, qui est la valeur de la chaîne'theTop'
. -
il n'est pas possible d'écrire des initialisateurs d'objets (littéraux) avec des clés variables.
les trois seules options sont
IdentifierName
(passe en chaîne littérale),StringLiteral
, etNumericLiteral
(passe également en chaîne de caractères).
les règles ont changé pour ES6: https://stackoverflow.com/a/2274327/895245
j'ai utilisé ce qui suit pour ajouter une propriété avec un nom "dynamique" à un objet:
var key = 'top';
$('#myElement').animate(
(function(o) { o[key]=10; return o;})({left: 20, width: 100}),
10
);
key
est le nom de la nouvelle propriété.
l'objet des propriétés passées à animate
sera {left: 20, width: 100, top: 10}
c'est juste utiliser la notation []
comme recommandé par les autres réponses, mais avec moins de lignes de code!
ajouter des crochets autour de la variable fonctionne bien pour moi. Essayez
var thetop = 'top';
<something>.stop().animate(
{ [thetop] : 10 }, 10
);
code donné:
var thetop = 'top';
<something>.stop().animate(
{ thetop : 10 }, 10
);
traduction:
var thetop = 'top';
var config = { thetop : 10 }; // config.thetop = 10
<something>.stop().animate(config, 10);
comme vous pouvez le voir, la déclaration { thetop : 10 }
n'utilise pas la variable thetop
. Au lieu de cela, il crée un objet avec une clé nommée thetop
. Si vous voulez que la clé soit la valeur de la variable thetop
, alors vous devrez utiliser des crochets autour de thetop
:
var thetop = 'top';
var config = { [thetop] : 10 }; // config.top = 10
<something>.stop().animate(config, 10);
la syntaxe des crochets carrés a été présenté avec ES6. Dans les versions précédentes de JavaScript, vous auriez à faire ce qui suit:
var thetop = 'top';
var config = (
obj = {},
obj['' + thetop] = 10,
obj
); // config.top = 10
<something>.stop().animate(config, 10);
de cette façon aussi vous pouvez atteindre la sortie désirée
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>
ES5 mise en œuvre assigner des touches ci-dessous:
var obj = Object.create(null),
objArgs = (
(objArgs = {}),
(objArgs.someKey = {
value: 'someValue'
}), objArgs);
Object.defineProperties(obj, objArgs);
j'ai joint un fragment que j'ai utilisé pour convertir en objet nu.
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);