Как использовать переменную в качестве ключа в объектном литературе JavaScript?
Почему код ниже работает?
<something>.stop().animate(
{ 'top' : 10 }, 10
);
А следующий код не работает:
var thetop = 'top';
<something>.stop().animate(
{ thetop : 10 }, 10
);
Чтобы было еще яснее: в данный момент я не могу передать CSS-свойство в функцию animate как переменную.
5 ответ(ов)
В спецификации ECMAScript 5 (ES5) действительно говорится о том, что использование переменных в объектных литералах (инициализаторах) не поддерживается. Для ясности, вот что утверждают правила в спецификации:
Согласно разделу 11.1.5 спецификации ECMAScript 5, имена свойств (PropertyName) могут быть только трех типов:
IdentifierName
- это имя, которое интерпретируется как строка;StringLiteral
- прямо выраженная строка;NumericLiteral
- числовое значение, которое также преобразуется в строку.
Таким образом, при написании объекта вида { theTop: 10 }
ключ theTop
интерпретируется как IdentifierName
, который затем преобразуется в строковое значение 'theTop'
. Это означает, что { theTop: 10 }
эквивалентно { 'theTop': 10 }
.
Но стоит заметить, что вы не можете использовать переменные в объектных литералах. Если вы попытаетесь сделать что-то вроде { [variableName]: value }
, то это будет работать только в ES6 и выше (где разрешено использование вычисляемых свойств), но в ES5 это не допустимо.
Таким образом, по правилам ES5, вы можете использовать только фиксированные строковые или числовые имена свойств, в то время как для динамической генерации ключей вам будет нужно прибегнуть к альтернативным методам, таким как использование функции Object.defineProperty
или объявление объектов через Object.create
.
Если вы пытаетесь добавить данные в объект, используя "ключ:значение" из другого источника, вы можете использовать следующий подход:
let obj = {};
let key = "foo";
let value = "bar";
obj[`${key}`] = value;
// `console.log(obj)` вернет:
// {foo: "bar"}
// `typeof obj` вернет:
// "object"
Надеюсь, это кому-то поможет 😃
Вы можете использовать следующий код, чтобы добавить свойство с "динамическим" именем к объекту:
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
);
Это позволяет динамически использовать значения переменной в качестве ключей объекта, что удобно в вашем случае.
Вы также можете попробовать сделать это следующим образом:
const arr = [{
"description": "THURSDAY",
"count": "1",
"date": "2019-12-05"
},
{
"description": "WEDNESDAY",
"count": "0",
"date": "2019-12-04"
}]
const res = arr.map(value => {
return { [value.description]: { count: value.count, date: value.date } }
})
console.log(res);
Этот код создает новый массив, где каждый элемент представляет собой объект, ключом которого является значение description
, а значением — объект с полями count
и date
. Получившийся массив будет содержать структуры данных, соответствующие описанным требованиям.
Проверка существования переменной в JavaScript (определена/инициализирована)
Как добавить пару ключ/значение в объект JavaScript?
Проверка существования вложенного ключа объекта JavaScript
Как перечислить свойства объекта JavaScript?
Определение глобальной переменной в функции JavaScript