Optional Chaining ?.
В одной фразе: ?. прерывает вычисление цепочки и возвращает undefined если левая часть null или undefined, вместо броска TypeError. Незаменим при работе с глубоко вложенными структурами и ответами внешних API.
// Три синтаксические формы: .prop, .(), [expr]const resp = { data: null };
// resp.data.user.name → TypeError: Cannot read properties of null
resp.data?.user?.name; // undefined — property accessresp.data?.getUser?.(); // undefined — метод не вызван, нет TypeErrorresp.data?.['user']?.name; // undefined — computed key// Short-circuit: правая часть не вычисляется вообщеlet called = false;const sideEffect = () => { called = true; return 'x'; };
const obj = null;obj?.method(sideEffect()); // sideEffect НЕ вызвана!console.log(called); // false — важно для производительности и side-effects
// Комбо с ?? для дефолтных значенийfunction getCity(api) { return api?.user?.address?.city ?? 'Unknown';}// Важный нюанс: ?. проверяет только null/undefined, не "callable"const obj = { greet: null };
obj.greet?.(); // undefined — greet равно null, вызов пропущенobj.missing?.(); // undefined — missing === undefined, вызов пропущен
const obj2 = { greet: 'hello' };// obj2.greet?.() → TypeError: obj2.greet is not a function// ?. "прошёл" т.к. greet не null/undefined, но вызов строки — TypeError
// Нельзя слева от присваивания:// obj?.prop = 1 → SyntaxErrorИтог: ?. “short-circuits”: при null/undefined вся правая часть не вычисляется. Работает только для чтения — слева от присваивания запрещён.