web-dev-qa-db-fra.com

Comment utiliser une variable pour une clé dans un littéral d'objet JavaScript?

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.

302
speendo

{ 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.

510
Andy E

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
}

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)

thetop sera remplacé par la valeur de la variable.

94
kube

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:

  1. 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:

  1. Renvoie le SV [Valeur de chaîne] du StringLiteral.

La production PropertyName: NumericLiteral est évaluée comme suit:

  1. Soit nbr le résultat de la formation de la valeur de NumericLiteral.
  2. Retour à la chaîne (nbr).

Cela signifie que:

  • { theTop : 10 } est exactement le même que { 'theTop' : 10 }

    La PropertyNametheTop 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!

5
Phil M

L'ajout de crochets autour de la variable me convient. Essaye ça 

var thetop = 'top';
<something>.stop().animate(
    { [thetop] : 10 }, 10
);
4
Vaishali

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));
1
Dieter Schmitt

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);
1
Benny Neugebauer

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
)
0
sh32my

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>

0
Deepu Reghunath

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
0
ROROROOROROR

Vous pouvez le faire de cette façon:

var thetop = 'top';
<something>.stop().animate(
    new function() {this[thetop] = 10;}, 10
);
0
Yury Laykov

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);

0
darcher