Как стать автором
Обновить

Комментарии 15

НЛО прилетело и опубликовало эту надпись здесь
В ожидании включения предложения «optional chaining» в EcmaScript комитетом TC39, можно пользоваться очень удобной библиотекой, которая оборачивает опасный доступ ко вложенному значению с помощью магии в виде try/catch + regex.

github.com/facebookincubator/idx

Важное дополнение: в комплекте также идет babel-plugin, который позволяет превратить эту конструкцию в набор тернарных операторов, чтобы избавиться от try/catch в продакшене.

Частично могут помочь появившиеся в ES6 параметры функций по умолчанию. С их использованием по крайней мере внутри функций уже не нужно делать подобные проверки. Ну а из предложенного — optional chaining выглядит вполне достойно.
Частично помогает Typescript в строгом режиме. По опыту, в большинстве случаев проверка на undefined/null делается не потому что там и в самом деле может не оказаться объекта — а просто на всякий случай. Статическая типизация способна значительно уменьшить количество «всяких случаев».
Почему самой нелюбимой? Вполне любимая, если смотреть на то, что функции возвращают.
Хороший вариант, годный. Но! Вариант с вопросом тоже избыточный, на мой взгляд. Вот смотрите:

a = obj?.prop1?.prop2.?prop3?;

А теперь, часто вам попадается такой; вариант:

a = obj?.prop1?.prop2.prop3?;

Наверное нечасто! Тем, кто не заметил: идет обращение к свойству свойства prop2 без контроля на null.

Я предложил бы писать так:

a = ?obj.prop1.prop2.prop3;

То есть контролировать все этапы получения значения в выражении, перед которым условный символ, скажем наш ?, причём для странных ситуаций, где в середине выражения проверки не нужны, скобки помогут.
Мне кажется, Вы не вполне точно изложили семантику null-а. В спецификации сказано: primitive value that represents the intentional absence of any object value.
Мне кажется, правильнее всего просто избегать подобных проблем:
let obj = {};
console.log(obj.someProp); //ошибки не будет


Ну или если мы совсем не влияем на то что к нам приходит:
if (typeof obj === "object") {
    console.log(obj.someProp); //ошибки не будет
} else {
    ...
}
Код с прокси не очень корректный. Если, например, требуемое конечное значение — объект, то у нас вернется проксированный вариант, возвращающий дефолтное значение в случае отсутствия свойства

...
const obj = {
  items: [{ someObj: {} }]
};

const someObj = optional(obj, target => target.items[0].someObj, "def");
console.log(someObj.someProp) // "def"


ну и вызов proxify со вторым аргументом не нужен — proxify принимает один аргумент
НЛО прилетело и опубликовало эту надпись здесь
((obj.prop1 || {}).prop2 || {}).prop3
За что минусы?

Куча скобочек из ниоткуда, превращающих чтение кода в игру "найди пару". Плюс false, 0 и пустая строка превращаются в пустой объект, что может оказаться багом. А уж вызов метода в таком стиле выглядит еще страшнее:


(obj.prop1 || (() => {}))();
false, 0 и пустая строка превращаются в пустой объект

На практика в большинстве случаев можно расчитывать, что на месте prop1 или prop2 может быть только объект, null и undefined, а prop3 уже не заменяется.


А уж вызов метода в таком стиле выглядит еще страшнее

я и не говорил, что решение универсальное, в каких-то случаях подходит, в каких-то нет. Скажем a?.b я бы на сегодняшний день записал как a && a.b, а вот конструкцию a.b.c.d?.e однозначно как (a.b.c.d || {}).e, вариант a.b.c.d && a.b.c.d.e при не односимвольных именах будет заметно длиннее.

Зарегистрируйтесь на Хабре, чтобы оставить комментарий