Null vs.Undefined
Darmowy film na youtube na ten temat
JavaScript (a przez rozszerzenie TypeScript) ma dwa dolne typy:null
Iundefined
. Mają one oznaczać różne rzeczy:
-
coś nie zostało zainicjowane:
undefined
. -
coś jest obecnie niedostępne:
null
.
faktem jest, że będziesz musiał poradzić sobie z obydwoma. Co ciekawe w JavaScript z ==
null
I undefined
są sobie równe:
// Both null and undefined are only `==` to themselves and each other:console.log(null == null); // true (of course)console.log(undefined == undefined); // true (of course)console.log(null == undefined); // true// You don't have to worry about falsy values making through this checkconsole.log(0 == undefined); // falseconsole.log('' == undefined); // falseconsole.log(false == undefined); // false
Poleć == null
aby sprawdzić zarówno undefined
lub null
. Generalnie nie chcesz rozróżniać między tymi dwoma.
function foo(arg: string | null | undefined) {if (arg != null) {// arg must be a string as `!=` rules out both null and undefined.}}
Możesz również zrobić
== undefined
, ale== null
jest bardziej konwencjonalny / krótszy.
jeden wyjątek, poziom głównyundefined
wartości, które omówimy dalej.
sprawdzanie poziomu root undefined
pamiętasz, jak powiedziałem, że powinieneś użyć== null
? Oczywiście, że tak (bo właśnie to powiedziałem ^). Nie używaj go do root level rzeczy. W trybie strict jeśli użyjeszfoo
Ifoo
jest niezdefiniowany, otrzymaszReferenceError
wyjątek i cały stos wywołań zostanie rozwinięty.
powinieneś użyć trybu ścisłego … w rzeczywistości kompilator TS wstawia go za Ciebie, jeśli używasz modułów … więcej o tych w dalszej części książki, więc nie musisz być o tym jednoznaczny 🙂
aby sprawdzić, czy zmienna jest zdefiniowana, czy nie na poziomie globalnym, zwykle używasz typeof
:
if (typeof someglobal !== 'undefined') {// someglobal is now safe to useconsole.log(someglobal);}
ogranicz jawne użycie Undefined
ponieważ TypeScript daje Ci możliwość dokumentowania Twoich struktur oddzielnie od wartości zamiast takich rzeczy jak:
function foo(){// if Somethingreturn {a:1,b:2};// elsereturn {a:1,b:undefined};}
powinieneś użyć adnotacji typu:
function foo():{a:number,b?:number}{// if Somethingreturn {a:1,b:2};// elsereturn {a:1};}
wywołania zwrotne w stylu węzła
funkcje zwrotne w stylu węzła (np. (err,somethingElse)=>{ /* something */ }
) są zwykle wywoływane z err
ustawione na null
jeśli nie ma błędu. Zwykle po prostu używasz prawdziwego sprawdzenia dla tego:
fs.readFile('someFile', 'utf8', (err,data) => {if (err) {// do something} else {// no error}});
podczas tworzenia własnych interfejsów API można użyćnull
w tym przypadku dla spójności. W całej szczerości dla własnych API powinieneś spojrzeć na obietnice, w tym przypadku nie musisz się martwić o brak wartości błędu (obsługujesz je za pomocą .then
vs. .catch
).
nie używaj undefined jako środka oznaczającego poprawność
na przykład okropną funkcję taką jak ta:
function toInt(str: string) {return str ? parseInt(str) : undefined;}
można znacznie lepiej zapisać w ten sposób:
function toInt(str: string): { valid: boolean, int?: number } {const int = parseInt(str);if (isNaN(int)) {return { valid: false };}else {return { valid: true, int };}}
JSON i serializacja
standard JSON obsługuje kodowanienull
, ale nieundefined
. Podczas kodowania JSON obiektu z atrybutem null
, atrybut zostanie dołączony z jego wartością null, podczas gdy atrybut z wartością undefined
zostanie całkowicie wykluczony.
JSON.stringify({willStay: null, willBeGone: undefined}); // {"willStay":null}
w rezultacie bazy danych oparte na JSON mogą wspieraćnull
wartości, ale nieundefined
wartości. Ponieważ atrybuty ustawione na null
są zakodowane, możesz przesłać zamiar wyczyszczenia atrybutu, ustawiając jego wartość na null
przed zakodowaniem i przesłaniem obiektu do zdalnego sklepu.
ustawienie wartości atrybutów na undefined może zaoszczędzić na kosztach przechowywania i transmisji, ponieważ nazwy atrybutów nie będą zakodowane. Może to jednak skomplikować semantykę usuwania wartości w porównaniu z wartościami nieobecnymi.
ostatnie przemyślenia
zespół maszynopisu nie używanull
: Wskazówki dotyczące kodowania maszynopisu i nie sprawiło to żadnych problemów. Douglas Crockford uważa, że null
to zły pomysł i wszyscy powinniśmy po prostu użyć undefined
.
jednak bazy kodu stylu NodeJS używająnull
dla argumentów błędów jako standard, ponieważ oznaczaSomething is currently unavailable
. Osobiście nie dbam o rozróżnienie między tymi dwoma, ponieważ większość projektów korzysta z bibliotek o różnych opiniach i po prostu wyklucza oba z == null
.