Литерал объекта Javascript: что такое {a, b, c}?

88

Вопрос, который у меня есть, лучше всего задать с помощью этого jsfiddle , код которого приведен ниже:

var a = 1, b = 'x', c = true;

var d = {a: a, b: b, c: c}; // <--- object literal
var e = [a, b, c];          // <--- array
var f = {a, b, c};          // <--- what exactly is this??

// these all give the same output:
alert(d.a  + ', ' + d.b +  ', ' + d.c );
alert(e[0] + ', ' + e[1] + ', ' + e[2]);
alert(f.a  + ', ' + f.b +  ', ' + f.c );

Что это за структура данных f? Это просто сокращение d?

Drmrbrewer
источник
25
Первый на самом деле не JSON.
GolezTrol
1
ОК @GolezTrol, это не строго JSON, потому что ключи не в двойных кавычках. Так как именно вы бы назвали dструктуру данных в моем сообщении?
drmrbrewer
6
Важно понимать, что ни одна из версий не является действительной JSON. Способ представления данных в виде строки JSON:{"a" : 1, "b" : "x", "c" : true }
Бенджамин Грюнбаум
14
@drmrbrewer Это литерал объекта . это не JSON, потому что это код javascript , тогда как JSON - это формат сериализации. Например var a = '{ "a" : "value"}'-> aсодержит строку, которая может быть десериализована в объект через JSON.parse.
moonwave99

Ответы:

71

Это сокращение свойства инициализатора объекта в ES6.

var f = {a, b, c, d:1}; // Will be equal to {a:a, b:b, c:c, d:1}

Это работает, потому что значение свойства имеет то же имя, что и идентификатор свойства. Это новое дополнение к синтаксису Object Initialiser ( раздел 11.1.5 ) в последней версии ECMAScript 6 draft Rev 13 . И, конечно же, как и ограничения, установленные в ECMAScript 3, вы не можете использовать зарезервированное слово в качестве имени своего свойства.

Такое сокращение не сильно изменит ваш код, оно только сделает все немного слаще!

function createCar(name, brand, speed) {
  return { type: 'Car', name: name, brand: brand, speed: speed };
}

// With the new shorthand form
function createSweetCar(name, brand, speed) {
  return { type: 'Car', name, brand, speed }; // Yes it looks sweet.
}

См. Таблицу совместимости для поддержки этих обозначений. В неподдерживаемых средах эти обозначения приведут к синтаксическим ошибкам.

Эта сокращенная запись довольно хорошо предлагает сопоставление объектов:

В ECMAScript5 то, что мы делали раньше:

var tmp = getData();
var op  = tmp.op;
var lhs = tmp.lhs;
var rhs = tmp.rhs;

Это можно сделать в ECMAScript6 с помощью одной строки кода:

var { op, lhs, rhs } = getData();
пустота
источник
10
Почему это могло быть так полезно, чтобы стать функцией языка? Похоже, что для людей было бы гораздо чаще либо инициализировать объект напрямую с помощью литералов, возвращаемых значений и т.д., либо просто сначала создать объект, а затем напрямую установить свойства. Создание переменных с одинаковыми именами, создание их экземпляров, а затем, наконец, инициализация такого объекта, кажется необычным ... или нет?
Panzercrisis
3
@Panzercrisis Лично мне кажется, что это приведет к множеству непреднамеренных и трудных для поиска ошибок. Примерно так же, if(a = 1) {...}как и допустимый синтаксис.
Энтони Грист,
1
@Panzercrisis Я думаю, что по крайней мере имеет смысл, если вы представите, что a, b и c являются более сложными структурами данных, а f также содержит другие сложные свойства. Все еще не уверен, что это отличная идея, но я видел, что это полезно.
Джош Рамбут
1
@Panzercrisis может быть очень полезно вернуть кортеж из лямбда-функции, например (a, b) => {a, b}. По крайней мере, так я использовал ту же функцию в C#.
Винсент ван дер Виле,
2
@Alex, как это "причуда" или "комплекс"? Очень распространенная вещь, которую вы обычно найдете во многих базах кода, - это инициализация объекта, где ключ соответствует переменной, заданной как значение {id: id, data: data, isSelected: isSelected}и т. Д. Часто случается при сопоставлении входящих объектов с локальными и затем обратно. В большинстве случаев вы не хотите называть свои вещи немного по-другому {identifier: id, viewData: data, isElementSelected: isSelected }- это именно те «причудливые», «сложные» и «запутанные», о которых вы говорите.
ВЛАЗ
77
var f = {a, b, c};

Он поставляется с ES6 (ECMAScript 2015) и означает то же самое, что:

var f = {a: a, b: b, c: c};

Он называется сокращенным обозначением значения свойства литерала объекта (или просто сокращением значения свойства, сокращенным обозначением свойств).

Вы также можете комбинировать сокращение с классической инициализацией:

var f = {a: 1, b, c};

Для получения дополнительной информации см. Инициализатор объекта .

madox2
источник
12
var f = {a, b, c};          // <--- what exactly is this??

Он определяет объект в JavaScript с использованием новой нотации ECMAScript 2015:

Согласно сети разработчиков Mozilla :

"Объекты можно инициализировать с помощью new Object (), Object.create () или с использованием буквальной нотации (нотация инициализатора). Инициализатор объекта - это список из нуля или более пар имен свойств и связанных значений объекта, заключенных в фигурные скобки ({})."

var a = "foo", 
    b = 42, 
    c = {};

// Shorthand property names (ES6)
var o = { a, b, c }; 

эквивалентно:

var a = "foo", 
    b = 42,
    c = {};

var o = { 
  a: a,
  b: b,
  c: c
};
MojoJojo
источник