Menu

Operator ?? w JavaScript: wartości domyślne zrobione dobrze

Jak operator ?? wybiera wartość domyślną tylko wtedy, gdy wartość to null lub undefined, i dlaczego w większości realnych przypadków jest lepszy od ||.

Na tej stronie są działające edytory: edytuj, uruchamiaj i od razu zobacz wynik.

Mądrzejsza wartość domyślna

JavaScript od zawsze miał skrót do wartości domyślnych: value || fallback. Zwykle działa, ale ma wbudowany błąd: traktuje każdą wartość falsy jako brakującą. 0, '' i false uruchamiają wartość zapasową, nawet gdy są prawdziwą odpowiedzią.

Operator nullish coalescing ?? to naprawia. Sięga po wartość zapasową tylko przy null lub undefined:

0 i '' przetrwały. null i undefined nie. To cały operator.

Dlaczego || nie wystarcza

Oto klasyczny błąd, któremu ?? miał zapobiegać:

Użytkownik poprosił o głośność 0 (cisza) i pusty pseudonim. Obie wartości zostały po cichu nadpisane, bo || nie odróżnia "brakującego" od "falsy".

Podmień na ??:

Teraz 0 i '' przechodzą nietknięte, a wartość domyślną dostają tylko pola, których naprawdę brakuje. Prawie zawsze właśnie o to chodzi.

Model myślowy

?? zadaje jedno pytanie: czy lewa strona to null lub undefined? Nic innego się nie liczy.

Wartośćlewa || prawa zwracalewa ?? prawa zwraca
nullprawaprawa
undefinedprawaprawa
0prawalewa (0)
''prawalewa ('')
falseprawalewa (false)
NaNprawalewa (NaN)
dowolny obiektlewalewa

Wybierz ??, gdy twoje dane mają znaczące wartości falsy. Wybierz ||, gdy naprawdę chcesz odrzucić wszystko, co falsy (krótkie stringi, zerowe liczniki itp.). Taki przypadek istnieje, ale jest rzadszy, niż się wydaje.

Skrócone obliczanie

Tak jak || i &&, ?? stosuje skrócone obliczanie. Jeśli lewa strona nie jest nullish, prawa w ogóle się nie wykonuje:

expensiveDefault() wykonuje się tylko raz, dla b. To przydatne, gdy wartość zapasowa to wywołanie funkcji, zapytanie sieciowe albo cokolwiek innego, co wolisz pominąć, gdy nie jest potrzebne.

W parze z optional chaining

?? i ?. weszły razem w ES2020 i zaprojektowano je do pracy w zespole. Optional chaining przechodzi przez ścieżkę, której może brakować, i zwraca undefined, jeśli brakuje któregoś kroku. Nullish coalescing uzupełnia wtedy sensowną wartość domyślną:

Bez tej pary ten sam kod to brzydki łańcuch sprawdzeń && albo try/catch. Z nią bezpieczny dostęp i rozsądne wartości domyślne mieszczą się w jednej linii.

Przypisanie nullish: ??=

a ??= b przypisuje b do a tylko wtedy, gdy a to null lub undefined. To operator logicznego przypisania nullish i stosuje skrócone obliczanie: jeśli a ma już wartość, prawa strona nie jest obliczana.

Zauważ, że verbose: false i retries: 0 zostały zachowane: ??= uzupełnia tylko to, czego naprawdę brakuje. Porównaj z ||=, który nadpisałby obie wartości.

Priorytet i zasada nawiasów

?? celowo odmawia mieszania z || lub && bez nawiasów. To rzuca SyntaxError:

const x = a || b ?? c;   // SyntaxError

Twórcy języka uznali, że priorytet jest na tyle niejednoznaczny, że warto zmusić cię do doprecyzowania. Dodaj nawiasy i wszystko działa:

Inne grupowanie, inna odpowiedź. Nawiasy nie są ozdobą: mówią przyszłym czytelnikom (i parserowi), o co ci chodzi.

To nie to samo co parametr domyślny

Parametry domyślne w sygnaturach funkcji mają własną zasadę: włączają się tylko wtedy, gdy argument to undefined, a nie null. To subtelna różnica względem ??, który traktuje obie wartości tak samo.

Jeśli chcesz, żeby null też uruchamiało wartość zapasową, użyj ?? w ciele funkcji:

Mała różnica, o którą łatwo się potknąć, gdy API zwraca null jako "nie ustawiono wartości".

Kiedy sięgać po ??

Używaj ?? jako domyślnego operatora, chyba że masz konkretny powód, żeby tego nie robić. To on pasuje do tego, jak naprawdę zachowuje się większość danych: 0, '' i false to zwykle prawdziwe wartości, które warto zachować, a wartość zapasowa należy się tylko danym, których naprawdę brakuje. || zostaw na przypadki, w których rzeczywiście chcesz zastąpić każdą wartość falsy.

Dalej: klasy

To tyle o obiektach i tablicach. Masz już narzędzia, żeby bezpiecznie budować i przeglądać struktury danych. Następny rozdział przechodzi do organizowania zachowania: klas, dziedziczenia i systemu prototypów, który za nimi stoi.

Najczęściej zadawane pytania

Czym jest operator nullish coalescing w JavaScript?

?? zwraca prawą stronę tylko wtedy, gdy lewa strona to null lub undefined. W przeciwnym razie zwraca lewą stronę bez zmian. value ?? fallback to standardowy sposób na podanie wartości domyślnej bez potykania się o wartości falsy, które są poprawne, takie jak 0 czy ''.

Jaka jest różnica między ?? a || w JavaScript?

|| sięga po wartość zapasową przy każdej wartości falsy: 0, '', false, NaN, null, undefined. ?? robi to tylko przy null i undefined. Jeśli 0 lub pusty string to w twoich danych poprawna wartość, użyj ??. Jeśli naprawdę chcesz odrzucić wszystkie wartości falsy, || nadal jest właściwym wyborem.

Czy można łączyć nullish coalescing z optional chaining?

Tak i to bardzo częste połączenie. user?.settings?.theme ?? 'light' bezpiecznie przechodzi przez łańcuch, zwraca undefined, jeśli czegoś po drodze brakuje, a potem podstawia 'light'. Oba operatory weszły razem w ES2020 właśnie po to, żeby obsłużyć ten wzorzec.

Co robi operator ??=?

a ??= b przypisuje b do a tylko wtedy, gdy a ma obecnie wartość null lub undefined. To logiczne przypisanie nullish, skrót od a = a ?? b, ale ze skróconym obliczaniem: jeśli a ma już wartość, prawa strona nie jest nawet obliczana. Przydaje się do uzupełniania brakujących wartości domyślnych w obiekcie opcji.

Ilustracja języków programowania w Coddy

Ucz się programowania z Coddy

ZACZNIJ