Pourquoi fonctionne ce qui suit?
<something>.stop().animate(
{ 'top' : 10 }, 10
);
Considérant que cela ne fonctionne pas:
var thetop = 'top';
<something>.stop().animate(
{ thetop : 10 }, 10
);
Pour être encore plus clair: pour le moment, je ne peux pas transmettre une propriété CSS à la fonction animate en tant que variable.
{ thetop : 10 }
est un objet littéral valide. Le code créera un objet avec une propriété nommée thetop
qui a la valeur 10. Les deux éléments suivants sont identiques:
obj = { thetop : 10 };
obj = { "thetop" : 10 };
Dans ES5 et les versions antérieures, vous ne pouvez pas utiliser une variable en tant que nom de propriété dans un littéral d'objet. 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éfinitComputedPropertyName dans le cadre de la grammaire des littéraux d'objet, ce qui vous permet d'écrire le code de la manière suivante:
var thetop = "top",
obj = { [thetop]: 10 };
console.log(obj.top); // -> 10
Vous pouvez utiliser cette nouvelle syntaxe dans les dernières versions de chaque navigateur grand public.
Avec ECMAScript 2015 , vous pouvez désormais le faire directement dans la déclaration d'objet avec la notation entre crochets:
var obj = {
[key]: value
}
Où key
peut être n’importe quel type d’expression (par exemple une variable) renvoyant une valeur.
Alors, votre code ressemblerait à ceci:
<something>.stop().animate({
[thetop]: 10
}, 10)
Où thetop
sera remplacé par la valeur de la variable.
ES5 citation qui dit que cela ne devrait pas fonctionner
Spec: http://www.ecma-international.org/ecma-262/5.1/#sec-11.1.5
Nom de la propriété :
- IdentifierName
- StringLiteral
- NumericLiteral
[...]
Le PropertyName de production: IdentifierName est évalué comme suit:
- Renvoie la valeur de chaîne contenant la même séquence de caractères que IdentifierName.
Le PropertyName de production: StringLiteral est évalué comme suit:
- Renvoie le SV [Valeur de chaîne] du StringLiteral.
La production PropertyName: NumericLiteral est évaluée comme suit:
- Soit nbr le résultat de la formation de la valeur de NumericLiteral.
- Retour à la chaîne (nbr).
Cela signifie que:
{ theTop : 10 }
est exactement le même que { 'theTop' : 10 }
La PropertyName
theTop
est une IdentifierName
; elle est donc convertie en la valeur de chaîne 'theTop'
, qui correspond à la valeur de chaîne de 'theTop'
.
Il n'est pas possible d'écrire des initialiseurs d'objet (littéraux) avec des clés variables.
Les trois seules options possibles sont IdentifierName
(se développe en chaîne littérale), StringLiteral
et NumericLiteral
(se développe également en chaîne).
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}
Ceci utilise simplement la notation []
requise comme recommandé par les autres réponses, mais avec moins de lignes de code!
L'ajout de crochets autour de la variable me convient. Essaye ça
var thetop = 'top';
<something>.stop().animate(
{ [thetop] : 10 }, 10
);
Je ne pouvais pas trouver un exemple simple sur les différences entre ES6 et ES5, alors j'en ai créé un. Les deux exemples de code créent exactement le même objet. Mais l'exemple ES5 fonctionne également dans les navigateurs plus anciens (comme IE11), contrairement à l'exemple ES6.
ES6
var matrix = {};
var a = 'one';
var b = 'two';
var c = 'three';
var d = 'four';
matrix[a] = {[b]: {[c]: d}};
ES5
var matrix = {};
var a = 'one';
var b = 'two';
var c = 'three';
var d = 'four';
function addObj(obj, key, value) {
obj[key] = value;
return obj;
}
matrix[a] = addObj({}, b, addObj({}, c, d));
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 constater, 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
, 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 entre crochets a été introduite avec ES6. Dans les versions antérieures de JavaScript, vous devez procéder comme suit:
var thetop = 'top';
var config = (
obj = {},
obj['' + thetop] = 10,
obj
); // config.top = 10
<something>.stop().animate(config, 10);
Vous pouvez effectuer les opérations suivantes pour ES5:
var theTop = 'top'
<something>.stop().animate(
JSON.parse('{"' + theTop + '":' + JSON.stringify(10) + '}'), 10
)
Ou extraire une fonction:
function newObj (key, value) {
return JSON.parse('{"' + key + '":' + JSON.stringify(value) + '}')
}
var theTop = 'top'
<something>.stop().animate(
newObj(theTop, 10), 10
)
De cette façon, vous pouvez également obtenir le résultat souhaité
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>
Si vous voulez que la clé d'objet soit identique au nom de variable, l'ES 2015 est abrégé . Nouvelles notations dans ECMAScript 2015
var thetop = 10;
var obj = { thetop };
console.log(obj.thetop); // print 10
Vous pouvez le faire de cette façon:
var thetop = 'top';
<something>.stop().animate(
new function() {this[thetop] = 10;}, 10
);
La mise en œuvre ES5 pour attribuer les clés est la suivante:
var obj = Object.create(null),
objArgs = (
(objArgs = {}),
(objArgs.someKey = {
value: 'someValue'
}), objArgs);
Object.defineProperties(obj, objArgs);
J'ai joint un extrait que j'avais l'habitude de 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);