5

Как использовать переменную в качестве ключа в объектном литературе JavaScript?

12

Почему код ниже работает?

<something>.stop().animate(
    { 'top' : 10 }, 10
);

А следующий код не работает:

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

Чтобы было еще яснее: в данный момент я не могу передать CSS-свойство в функцию animate как переменную.

5 ответ(ов)

0

В спецификации ECMAScript 5 (ES5) действительно говорится о том, что использование переменных в объектных литералах (инициализаторах) не поддерживается. Для ясности, вот что утверждают правила в спецификации:

Согласно разделу 11.1.5 спецификации ECMAScript 5, имена свойств (PropertyName) могут быть только трех типов:

  1. IdentifierName - это имя, которое интерпретируется как строка;
  2. StringLiteral - прямо выраженная строка;
  3. NumericLiteral - числовое значение, которое также преобразуется в строку.

Таким образом, при написании объекта вида { theTop: 10 } ключ theTop интерпретируется как IdentifierName, который затем преобразуется в строковое значение 'theTop'. Это означает, что { theTop: 10 } эквивалентно { 'theTop': 10 }.

Но стоит заметить, что вы не можете использовать переменные в объектных литералах. Если вы попытаетесь сделать что-то вроде { [variableName]: value }, то это будет работать только в ES6 и выше (где разрешено использование вычисляемых свойств), но в ES5 это не допустимо.

Таким образом, по правилам ES5, вы можете использовать только фиксированные строковые или числовые имена свойств, в то время как для динамической генерации ключей вам будет нужно прибегнуть к альтернативным методам, таким как использование функции Object.defineProperty или объявление объектов через Object.create.

0

Если вы пытаетесь добавить данные в объект, используя "ключ:значение" из другого источника, вы можете использовать следующий подход:

let obj = {};
let key = "foo";
let value = "bar";

obj[`${key}`] = value;

// `console.log(obj)` вернет:
// {foo: "bar"}

// `typeof obj` вернет:
// "object"

Надеюсь, это кому-то поможет 😃

0

Вы можете использовать следующий код, чтобы добавить свойство с "динамическим" именем к объекту:

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

Этот подход использует квадратные скобки [], что рекомендуется в других ответах, но при этом требует меньше строк кода!

0

Добавление квадратных скобок вокруг переменной действительно работает хорошо для меня. Попробуйте сделать так:

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

Это позволяет динамически использовать значения переменной в качестве ключей объекта, что удобно в вашем случае.

0

Вы также можете попробовать сделать это следующим образом:

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. Получившийся массив будет содержать структуры данных, соответствующие описанным требованиям.

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь