Как использовать переменную для ключа в литерале объекта JavaScript?
почему после работы?
<something>.stop().animate(
{ 'top' : 10 }, 10
);
в то время как это не работает:
var thetop = 'top';
<something>.stop().animate(
{ thetop : 10 }, 10
);
чтобы было еще яснее: на данный момент я не могу передать свойство CSS функции animate в качестве переменной.
8 ответов:
{ thetop : 10 }
является допустимым литералом объекта. Код создаст объект со свойством с именемthetop
это имеет значение 10. Как следующим же:obj = { thetop : 10 }; obj = { "thetop" : 10 };
в ES5 и более ранних версиях нельзя использовать переменную в качестве имени свойства внутри литерала объекта. Ваш единственный вариант-сделать следующее:
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 определяет ComputedPropertyName как часть грамматики для объектных литералов, которая позволяет писать код такой:
var thetop = "top", obj = { [thetop]: 10 }; console.log(obj.top); // -> 10
вы можете использовать этот новый синтаксис в последних версиях каждого основного браузера.
С ECMAScript 2015 теперь вы можете сделать это непосредственно в объявлении объекта с пометкой скобки:
var obj = { [key]: value }
здесь
key
может быть любое выражение (например, переменная), возвращающее значение.так вот ваш код будет выглядеть так:
<something>.stop().animate({ [thetop]: 10 }, 10)
здесь
thetop
будет заменено значением переменной.
ES5 цитата, которая говорит, что это не должно работать
Spec:http://www.ecma-international.org/ecma-262/5.1/#sec-11.1.5
Имя_свойства :
- IdentifierName
- StringLiteral
- NumericLiteral
[...]
production PropertyName: IdentifierName оценивается следующим образом:
- возвращает строковое значение, содержащее ту же последовательность символов, что и IdentifierName.
production PropertyName: StringLiteral оценивается следующим образом:
- возвращает SV [строковое значение] StringLiteral.
production PropertyName: NumericLiteral оценивается следующим образом:
- пусть nbr является результатом формирования значения Нумериклитерал.
- возвращает метод toString(бутадиен-нитрильный Каучук).
это означает, что:
{ theTop : 10 }
Это точно так же, как{ 'theTop' : 10 }
The
PropertyName
theTop
- этоIdentifierName
, поэтому он преобразуется в элемент'theTop'
строковое значение, которое является строковым значением'theTop'
.невозможно написать инициализаторы объектов (литералы) с переменными ключами.
только три варианты есть
IdentifierName
(расширяется до строкового литерала),StringLiteral
иNumericLiteral
(также расширяется до строки).правила изменились для ES6:https://stackoverflow.com/a/2274327/895245
я использовал следующее, Чтобы добавить свойство с "динамическим" именем к объекту:
var key = 'top'; $('#myElement').animate( (function(o) { o[key]=10; return o;})({left: 20, width: 100}), 10 );
key
- это имя нового свойства.объект недвижимости перешло к
animate
будет{left: 20, width: 100, top: 10}
Это просто с помощью
[]
обозначения, как рекомендовано другими ответами, но с меньшим количеством строк кода!
добавлять квадратные скобки вокруг переменной работает хорошо для меня. Попробуйте это
var thetop = 'top'; <something>.stop().animate( { [thetop] : 10 }, 10 );
данный код:
var thetop = 'top'; <something>.stop().animate( { thetop : 10 }, 10 );
перевод:
var thetop = 'top'; var config = { thetop : 10 }; // config.thetop = 10 <something>.stop().animate(config, 10);
как вы можете видеть,
{ thetop : 10 }
объявление не использует переменнуюthetop
. Вместо этого он создает объект с ключом с именемthetop
. Если вы хотите, чтобы ключ был значением переменнойthetop
, тогда вам придется использовать квадратные скобкиthetop
:var thetop = 'top'; var config = { [thetop] : 10 }; // config.top = 10 <something>.stop().animate(config, 10);
синтаксис квадратных скобок был введен с ES6. В более ранних версиях JavaScript вам нужно было бы сделать следующее:
var thetop = 'top'; var config = ( obj = {}, obj['' + thetop] = 10, obj ); // config.top = 10 <something>.stop().animate(config, 10);
таким образом, вы также можете достичь желаемого результата
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 для назначения ключей находится ниже:
var obj = Object.create(null), objArgs = ( (objArgs = {}), (objArgs.someKey = { value: 'someValue' }), objArgs); Object.defineProperties(obj, objArgs);
я прикрепил фрагмент, который я использовал для преобразования в голый объект.
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);