Краткий/краткий синтаксис для «необязательных» ключей объекта в ES6/ES7?

В ES6/ES7 уже есть много отличных функций для определения объектов Javascript. Однако в Javascript распространен следующий шаблон:

const obj = { 
  requiredKey1: ..., 
  requiredKey2: ... 
};

if (someCondition) { 
  obj.optionalKey1 = ...;
}

Есть ли способ определить объект сразу как с необязательными, так и с обязательными ключами?


person Andrew Mao    schedule 19.12.2017    source источник
comment
Почему бы просто не использовать тройку? optionKey1: someCondition ? value : undefined?   -  person Andrew Li    schedule 19.12.2017
comment
@FelixKling Я думаю, что это в значительной степени теоретическое различие, потому что не существует «полного» стандарта ES6 или ES7, реализованного в средах Node / браузера, и большинство людей все равно используют транспиляторы.   -  person Andrew Mao    schedule 20.12.2017
comment
Ну, это определяет рамки для ответов. Мы не знаем, что вы используете. Также я не хочу, чтобы люди неправильно использовали термин ES7 для экспериментальных функций.   -  person Felix Kling    schedule 20.12.2017
comment
@FelixKling Я спрашиваю о любом стандарте Ecmascript; очевидно, что существующие поддерживаемые стандарты лучше. Если это можно сделать с помощью экспериментальных функций, хорошо. Если это можно сделать с помощью ES6 или ES7, то лучше. Если это возможно с ES5, супер!   -  person Andrew Mao    schedule 20.12.2017
comment
Мне бы хотелось увидеть что-то вроде { key?: optionalValue } или сокращенного свойства: { optionalValue? }   -  person cimak    schedule 15.11.2020


Ответы (3)


Вы можете использовать распространение объекта, чтобы иметь необязательное свойство:

let flag1 = true;
let flag2 = false;

const obj = { 
  requiredKey1: 1, 
  requiredKey2: 2,
  ...(flag1 && { optionalKey1: 5 }),
  ...(flag2 && { optionalKey2: 6, optionalKey3: 7 }),
  ...(flag1 && { optionalKey4: 8, optionalKey5: 9 })
};

console.log(obj);

person Ori Drori    schedule 19.12.2017
comment
Примечание: это превратит любые геттеры в статические значения. - person Ryan King; 26.02.2020
comment
Как примечание, вам не нужны круглые скобки. например. ...flag1 && { optionalKey1: 5 }, тоже нормально. - person MattCochrane; 08.06.2020
comment
@RyanKing, можешь дать образец? {get x() {return this.a + this.b}, b: 2, ...a && {a}} работает как положено - person zb'; 09.04.2021
comment
@RyanKing а, необязательный геттер;) или вы не можете уничтожить геттер;) - person zb'; 13.04.2021
comment
Я получаю сообщение об ошибке в ложном значении, я решил это: ... (flag2 && { optionalKey2: 6, optionalKey3: 7 }) как {}, - person juanjinario; 21.07.2021

Для указания клавиши optional можно присвоить ей null, если условие ложно

const someCondition = true;

const obj = { 
  requiredKey1: 1, 
  requiredKey2: 2,
  optionalKey1: someCondition ? 'optional' : null
};

console.log(obj);

person Suren Srapyan    schedule 19.12.2017
comment
Хороший ответ, но стоит отметить, что при этом optionalKey1 по-прежнему отображается как один из ключей объекта, если условие ложно (и имеет значение null), тогда как исходный фрагмент OP создаст объект, в котором полностью отсутствует ключ, если условие ложно. - person CRice; 19.12.2017
comment
Я думаю, присвоение null свойству более понятно, что оно необязательно и не имеет значения, чем проверка на существование - person Suren Srapyan; 19.12.2017
comment
Я лично хотел бы получить какую-то ошибку и, вообще, любое поведение, которое язык (и JavaScript в частности) дал бы мне при попытке доступа к несуществующему свойству, а не делать его обнуляемым, поскольку это никогда будет иметь значение, в отличие от того, для чего используются обнуляемые значения - если оно должно существовать, оно существует. Если ему не нужно выходить, то нет - я думаю, это имеет больше смысла. - person Gal Grünfeld; 01.12.2020

следующий шаблон распространен в Javascript

Не должно. Наличие большого количества объектов разной формы может привести к снижению производительности. Записи всегда должны содержать одни и те же ключи. Так что просто используйте

const obj = { 
  requiredKey1: …, 
  requiredKey2: …,
  optionalKey1: someCondition ? … : undefined,
};
person Bergi    schedule 20.12.2017
comment
Шаблон действительно полезен для объектов, которые вы передаете в качестве параметров. - person krulik; 10.12.2019
comment
@krulik Параметры объекта Option обычно могут прекрасно работать со свойствами undefined, не отличая их от несуществующих свойств. - person Bergi; 10.12.2019