Необязательная логика цепочки

Я не уверен, что понимаю логику js-реализации необязательной цепочки.

const a = {b:1}

1 > console.log(a?.c)     => undefined
2 > console.log(a?.c?.d)  => undefined
3 > console.log(a?.c.d)   => Uncaught TypeError: Cannot read property 'd' of undefined

все имеет смысл до тех пор. Потом:

4 > console.log(a?.c?.d.e) => undefined
5 > console.log(a?.c?.d.e.f.g) => undefined

Доступ к свойству undefined вызывает ошибку (№3), но доступ к произвольному количеству несуществующих вложенных свойств после 2 необязательных цепочек больше не вызывает ошибок.


person alfredopacino    schedule 07.04.2020    source источник
comment
В этом вся идея. Если у вас есть ? после последнего отсутствующего свойства, остальная часть выражения работает, потому что она замыкается.   -  person Pointy    schedule 07.04.2020
comment
@Pointy, тогда почему в примере №3 возникает ошибка?   -  person alfredopacino    schedule 07.04.2020
comment
Поскольку a не равно нулю, но a.c равно undefined   -  person Pointy    schedule 07.04.2020
comment
@alfredopacino, потому что a не является ложью. Таким образом, вы получаете c от него, но у вас нет необязательной цепочки, поэтому вы выполняете обязательную цепочку (я предполагаю, что это противоположно необязательному), чтобы получить конкретное значение undefined и попробуй получить от него свойство d.   -  person VLAZ    schedule 07.04.2020
comment
Вы отмечаете место, где не уверены, работает ли доступ к свойствам, с помощью необязательной цепочки. Возьмем случай, когда вы уверены, что это объекты: a = { b: { c: { d: "value" }}} или a = {}. Вы говорите a?.b.c.d. Если это первый случай, он переходит в значение, если это второй, он просто заметит, что доступ к свойству .b не существует (undefined), поэтому он игнорирует все впоследствии и возвращает undefined. Однако, если у вас есть a = { b: {}}, то доступ к свойству для b не является неопределенным, и он оценит остальные, что выбрасывает.   -  person ASDFGerte    schedule 07.04.2020
comment
Другими словами, @ASDFGerte, a?.b - это a || a.b в старом синтаксисе, поэтому a?.b.c равно a || a.b.c - если a.b равно undefined, нет ничего, что могло бы остановить цепочку. В то время как a?.b?.c будет a || a.b || a.b.c, поэтому вы не должны пытаться получить .c из undefined.   -  person VLAZ    schedule 07.04.2020
comment
@alfredopacino может взглянуть на раздел короткого замыкания, определенный в предложении: github.com/tc39/proposal-optional-chaining/#short-circuiting   -  person Nick Parsons    schedule 07.04.2020


Ответы (1)


Комментарии к вопросу дают правильный ответ. Вот пояснение:

console.log(a.c)     // undefined
console.log(a.c.d)   // Uncaught TypeError: Cannot read property 'd' of undefined
console.log(a.c.d.e)   // Uncaught TypeError: Cannot read property 'd' of undefined
console.log(a.c?.d)  // undefined
console.log(a.c?.d.e) // undefined
console.log(a.c?.d.e.f.g) // undefined

Вы можете видеть, что оценка всегда останавливается на c, поскольку нет свойства a.c. Когда он останавливается, если вы использовали необязательный оператор цепочки (?.), Он возвращает undefined, в противном случае выдает ошибку.

Обратите внимание, что это новая функция. Для nodejs он появляется в версии 14, которая готова к производству (LTS) по состоянию на 2020/10/27.

person user1527225    schedule 21.08.2020