7 tipů pro nedefinované zpracování v JavaScriptu
Většina moderních jazyků jako Ruby, Python nebo Java má jednu nulovou hodnotu (nil
nebo null
), což se jeví jako rozumný přístup.
Ale JavaScript je jiný.
null
, ale také undefined
, představují v JavaScriptu prázdné hodnoty. Jaký je přesný rozdíl mezi nimi?
Krátká odpověď je, že interpret jazyka JavaScript vrací undefined
při přístupu k vlastnosti proměnné nebo objektu, která ještě není inicializována. Například:
Na druhé straně null
představuje chybějící objekt odkaz. JavaScript neinicializuje proměnné ani vlastnosti objektu pomocí null
.
Některé nativní metody, jako je String.prototype.match()
, mohou vrátit null
k označení chybějícího objektu. Podívejte se na ukázku:
Protože je JavaScript přípustný, vývojáři mají pokušení získat přístup k neinicializovaným hodnotám. I já jsem vinen z takové špatné praxe.
Takové riskantní akce často generují undefined
související chyby:
-
TypeError: "undefined" is not a function
-
TypeError: Cannot read property "<prop-name>" of undefined
- a podobné chyby typu.
Vývojář JavaScriptu dokáže pochopit ironii tohoto vtipu :
Abyste tyto chyby zmenšili, musíte pochopit případy, kdy undefined
je vygenerováno. Prozkoumejme undefined
a jeho vliv na bezpečnost kódu.
1. Co je nedefinováno
JavaScript má 6 primitivních typů:
A typ samostatného objektu: {name: "Dmitri"}
, .
Ze 6 primitivních typů undefined
je speciální hodnota s vlastním typem Nedefinováno. Podle specifikace ECMAScript:
Nedefinovaná hodnota primitivní hodnota se používá, pokud proměnné nebyla přiřazena hodnota.
Standard jasně definuje, že undefined
obdržíte při přístupu k neinicializovaným proměnným, vlastnostem neexistujících objektů, neexistující prvky pole a podobně.
Několik příkladů:
Výše uvedený příklad ukazuje, že přístup k:
- neinicializované proměnné
number
- vlastnost neexistujícího objektu
movie.year
- nebo neexistující prvek pole
movies
jsou vyhodnoceny jako undefined
.
Specifikace ECMAScript definuje typ hodnoty undefined
:
Nedefinovaný typ je typ, jehož jedinou hodnotou je
undefined
hodnota.
V tomto smyslu typeof
operátor vrací "undefined"
řetězec pro undefined
hodnotu:
Samozřejmě typeof
funguje dobře a ověřuje, zda proměnná obsahuje hodnotu undefined
:
2. Scénáře, které vytvářejí nedefinované
2.1 Neinicializovaná proměnná
Deklarovaná proměnná, která dosud nebyla přiřazena k hodnotě (neinicializovaná), je ve výchozím nastavení
undefined
.
Jednoduché a jednoduché:
myVariable
je deklarováno a dosud není přiřazeno s hodnotou. Přístup k proměnné se vyhodnotí na undefined
.
Efektivním přístupem k řešení problémů neinicializovaných proměnných je vždy, když je to možné, přiřadit počáteční hodnotu. Čím méně proměnná existuje v neinicializovaném stavu, tím lépe.
V ideálním případě byste hned po deklaraci const myVariable = "Initial value"
přiřadili hodnotu. Ale to není vždy možné.
Tip 1: Upřednostňujte const
, jinak použijte let
, ale rozloučte se s var
Podle mého názoru je jednou z nejlepších vlastností ECMAScript 2015 nový způsob deklarace proměnných pomocí const
a let
. Je to velký krok vpřed.
const
a let
jsou blokově vymezeny (na rozdíl od starších funkcí s rozsahem var
) a existují v časové mrtvé zóně až do řádku deklarace.
Doporučuji proměnnou const
, pokud se její hodnota nezmění. Vytváří neměnnou vazbu.
Jednou z příjemných vlastností const
je, že musíte proměnné const myVariable = "initial"
přiřadit počáteční hodnotu. Proměnná není vystavena neinicializovanému stavu a přístup k undefined
je nemožný.
Pojďme zkontrolovat funkci, která ověří, zda je slovo palindrom:
length
a half
jsou přiřazeny jednou hodnotou. Zdá se rozumné deklarovat je jako const
, protože tyto proměnné se nezmění.
Použijte let
deklaraci pro proměnné, jejichž hodnota se může změnit. Kdykoli je to možné, ihned přiřaďte počáteční hodnotu, např. let index = 0
.
A co stará škola var
? Můj návrh je přestat jej používat.
var
problém deklarace je zvedání proměnné v rámci rozsahu funkce. Proměnnou var
můžete deklarovat někde na konci rozsahu funkce, ale přesto k ní máte přístup před deklarací: a dostanete undefined
.
myVariable
je přístupný a obsahuje undefined
ještě před řádkem prohlášení: var myVariable = "Initial value"
.
Naopak k proměnné const
nebo let
nelze přistupovat před řádek deklarace – proměnná je před prohlášením v časové mrtvé zóně. A to je hezké, protože máte menší šanci získat přístup k undefined
.
Výše uvedený příklad byl aktualizován o let
(místo toho of var
) hodí ReferenceError
, protože proměnná v časové mrtvé zóně není přístupná.
Podpora používání const
pro neměnné vazby nebo let
jinak zajišťuje postup, který snižuje vzhled neinicializovaného proměnná.
Tip 2: Zvýšení soudržnosti
Soudržnost charakterizuje míru, do jaké patří prvky modulu (jmenný prostor, třída, metoda, blok kódu) k sobě. Soudržnost může být vysoká nebo nízká.
Výhodnější je modul s vysokou soudržností, protože prvky takového modulu se zaměřují pouze na jeden úkol. Díky tomu je modul:
- Zaměřený a srozumitelný: snazší pochopit, co modul dělá
- Udržovatelný a snazší refaktorovat: změna v modulu ovlivní méně modulů
- Opakovaně použitelné: protože je zaměřeno na jeden úkol, usnadňuje opětovné použití modulu.
- Testovatelné: jednodušší test modulu, který je zaměřen na jeden úkol,
Vysoká úroveň soudržnosti doprovázená volným spojením je charakteristikou dobře navrženého systému.
Blok kódu lze považovat za malý modul. Chcete-li těžit z výhod vysoké soudržnosti, udržujte proměnné co nejblíže bloku kódu, který je používá.
Pokud například existuje pouze proměnná, která tvoří logiku rozsahu bloku, pak deklarujte a zpřístupněte proměnnou pouze v tomto bloku (pomocí const
nebo let
prohlášení). Nevystavujte tuto proměnnou rozsahu vnějšího bloku, protože vnější blok by se o tuto proměnnou neměl starat.
Jedním z klasických příkladů zbytečně prodloužené životnosti proměnných je použití for
cyklus uvnitř funkce:
index
, item
a length
proměnné jsou deklarovány na začátku těla funkce. Používají se však až na konci. Jaký je problém s tímto přístupem?
Mezi deklarací nahoře a použitím v příkazu for
jsou proměnné index
, item
jsou neinicializovány a vystaveny undefined
. Mají nepřiměřeně dlouhý životní cyklus v celém rozsahu funkcí.
Lepším přístupem je přesunout tyto proměnné co nejblíže jejich místu použití:
index
a item
proměnné existují pouze v rozsahu bloku příkazu for
. Nemají žádný význam mimo for
.
length
proměnná je deklarována také poblíž zdroje jejího použití.
Proč je upravená verze lepší než původní? Podívejme se:
- Proměnné nejsou vystaveny neinicializovanému stavu, takže nemáte žádné riziko přístupu
undefined
- Přesunutí proměnné co nejblíže jejich místu použití zvyšují čitelnost kódu
- Vysoce soudržné bloky kódu lze snadněji refaktorovat a v případě potřeby extrahovat do samostatných funkcí
2.2 Přístup neexistující vlastnost
Při přístupu k neexistující vlastnosti objektu vrátí JavaScript
undefined
.
Ukážeme si to na příkladu:
favoriteMovie
je objekt s jedinou vlastností title
. Přístup k neexistující vlastnosti actors
pomocí přistupujícího objektu favoriteMovie.actors
bude vyhodnocen jako undefined
.
Přístup k neexistující vlastnosti nevyvolá chybu. Problém se objeví při pokusu o získání dat z neexistující vlastnosti, což je nejběžnější undefined
trap, který se projevuje ve známé chybové zprávě TypeError: Cannot read property <prop> of undefined
.
Pojďme mírně upravit předchozí fragment kódu pro ilustraci hodu TypeError
:
favoriteMovie
nemá vlastnost actors
, takže favoriteMovie.actors
vyhodnotí na undefined
.
Výsledkem je, že přístup k první položce hodnoty undefined
pomocí výrazu favoriteMovie.actors
vyvolá TypeError
.
Povolná povaha JavaScriptu, která umožňuje přístup k neexistujícím vlastnostem, je zdrojem nedeterminismu: vlastnost může být nastavena či nikoli. Dobrým způsobem, jak tento problém obejít, je omezit objekt tak, aby vždy definoval vlastnosti, které obsahuje.
Bohužel často nemáte kontrolu nad objekty. Takové objekty mohou mít různé sady vlastností v různých scénářích. Všechny tyto scénáře tedy musíte zpracovat ručně.
Implementujme funkci append(array, toAppend)
, která přidá na začátek a / nebo na konec pole nových prvků. toAppend
parametr přijímá objekt s vlastnostmi:
-
first
: prvek vložený na začátekarray
-
last
: prvek vložený na konecarray
.
Funkce vrací novou instanci pole, aniž by změnila původní pole.
První verze append()
, trochu naivní, může vypadat takto:
Protože toAppend
objekt může vynechat first
nebo last
vlastnosti, je nutné ověřit, zda tyto vlastnosti existují v toAppend
.
Přístupový objekt vlastnosti vyhodnotí undefined
, pokud vlastnost neexistuje. První pokušení zkontrolovat, zda jsou k dispozici vlastnosti first
nebo last
, je ověřit je proti undefined
. To se provádí v podmíněných podmínkách if(toAppend.first){}
a if(toAppend.last){}
…
Ne tak rychle. Tento přístup má nevýhodu. undefined
a false
, null
, 0
, NaN
a ""
jsou falešné hodnoty.
V aktuální implementaci append()
funkce neumožňuje vložit falešné prvky:
Následující tipy vysvětlují, jak správně zkontrolovat existenci nemovitosti.
Tip 3: Zkontrolovat existenci nemovitosti
Naštěstí JavaScript nabízí spousta způsobů, jak určit, zda má objekt konkrétní vlastnost:
-
obj.prop !== undefined
: porovnat sundefined
přímo -
typeof obj.prop !== "undefined"
: ověřte typ hodnoty vlastnosti -
obj.hasOwnProperty("prop")
: ověřte, zda objekt má vlastní vlastnost -
"prop" in obj
: ověřte, zda má objekt vlastní nebo zděděnou vlastnost
Moje doporučení je použijte operátor in
. Má krátkou a sladkou syntaxi. in
přítomnost operátora naznačuje jasný záměr zkontrolovat, zda má objekt konkrétní vlastnost, bez přístupu ke skutečné hodnotě vlastnosti.
obj.hasOwnProperty("prop")
je také pěkné řešení. Je o něco delší než in
operátor a ověřuje se pouze ve vlastních vlastnostech objektu.
Pojďme vylepšit funkci append(array, toAppend)
pomocí operátoru in
:
"first" in toAppend
(a "last" in toAppend
) je true
to, zda příslušná vlastnost existuje, false
jinak.
in
operátor opravuje problém s vložením falešných prvků 0
a false
. Přidáním těchto prvků na začátek a konec nyní vznikne očekávaný výsledek
.
Tip 4: Destrukturalizace pro přístup k vlastnostem objektu
Při přístupu k vlastnosti objektu je někdy nutné nastavit výchozí hodnotu, pokud vlastnost neexistuje.
K dosažení můžete použít in
doprovázený ternárním operátorem:
Syntax ternárních operátorů bude skličující, když se zvýší počet vlastností ke kontrole. Pro každou vlastnost musíte vytvořit nový řádek kódu pro zpracování výchozích hodnot, což zvyšuje ošklivou zeď podobně vypadajících ternárních operátorů.
Chcete-li použít elegantnější přístup, seznámíme se se skvělou funkcí ES2015 zvanou destrukce objektů.
Destrukce objektů umožňuje inline extrakci hodnot vlastností objektu přímo do proměnných a nastavení výchozí hodnoty, pokud vlastnost neexistuje. Pohodlná syntaxe, aby se zabránilo přímému jednání s undefined
.
Extrakce vlastností je nyní přesná:
Chcete-li vidět věci v akci, definujme užitečnou funkci, která zabalí řetězec do uvozovek.
quote(subject, config)
přijímá první argument jako řetězec, který má být zabalen. Druhým argumentem config
je objekt s vlastnostmi:
Uplatníme-li výhody destrukce objektu, implementujme quote()
:
const { char = """, skipIfQuoted = true } = config
destrukční přiřazení v jednom řádku extrahuje vlastnosti char
a skipIfQuoted
z config
objektu.
Pokud v objektu config
chybí některé vlastnosti, destrukční přiřazení nastaví výchozí hodnoty : """
pro char
a false
pro skipIfQuoted
.
Naštěstí má tato funkce stále prostor pro zlepšení.
Pojďme přesunout destrukční přiřazení do sekce parametrů. A nastavte výchozí hodnotu (prázdný objekt { }
) pro parametr config
, abyste přeskočili druhý argument, když stačí výchozí nastavení.
Přiřazení destrukce nahradí parametr config
v podpisu funkce. To se mi líbí: quote()
se zkrátí o jeden řádek.
= {}
na pravé straně destrukčního přiřazení zajišťuje, že bude použit prázdný objekt, pokud druhý argument není vůbec uveden quote("Sunny day")
.
Destrukce objektů je výkonná funkce, která efektivně zpracovává extrakci vlastností z objektů. Líbí se mi možnost zadat výchozí hodnotu, která se má vrátit, když přístupná vlastnost neexistuje. Ve výsledku se vyhnete undefined
a problémům kolem něj.
Tip 5: Vyplňte objekt výchozími vlastnostmi
Pokud není třeba vytvářet proměnné pro každou vlastnost, jak to dělá destrukční přiřazení, lze vyplnit objekt, který postrádá některé vlastnosti s výchozími hodnotami.
ES2015 Object.assign(target, source1, source2, ...)
zkopíruje hodnoty všech vyjmenovatelných vlastních vlastností z jednoho nebo více zdrojových objektů do cílového objektu. Funkce vrací cílový objekt.
Například musíte získat přístup k vlastnostem unsafeOptions
objektu, který nemusí vždy obsahovat celou sadu vlastností.
Abychom se vyhnuli undefined
při přístupu k neexistující vlastnosti z unsafeOptions
, udělejme několik úprav:
- Definujte objekt
defaults
, který obsahuje výchozí hodnoty vlastností - Zavolejte
Object.assign({ }, defaults, unsafeOptions)
k vytvoření nový objektoptions
. Nový objekt přijímá všechny vlastnosti zunsafeOptions
, ale chybějící jsou převzaty zdefaults
.
unsafeOptions
obsahuje pouze vlastnost fontSize
. Objekt defaults
definuje výchozí hodnoty pro vlastnosti fontSize
a color
.
Object.assign()
bere první argument jako cílový objekt {}
. Cílový objekt obdrží hodnotu fontSize
vlastnosti ze unsafeOptions
zdrojového objektu. A hodnota vlastnosti color
ze zdrojového objektu defaults
, protože unsafeOptions
neobsahuje color
.
Na pořadí, ve kterém jsou zdrojové objekty vyjmenovány, záleží: pozdější vlastnosti zdrojových objektů přepíší ty starší.
Nyní máte bezpečný přístup ke všem vlastnostem objektu options
, včetně options.color
, které nebyly k dispozici v unsafeOptions
zpočátku.
Naštěstí existuje jednodušší alternativa k vyplnění objektu výchozími vlastnostmi.Doporučuji použít vlastnosti šíření v inicializátorech objektů.
Místo Object.assign()
vyvolání použijte syntaxi šíření objektu ke zkopírování všech vlastních a vyjmenovatelných vlastností ze zdrojových objektů do cílového objektu:
Inicializátor objektů šíří vlastnosti ze defaults
a unsafeOptions
zdrojových objektů. Pořadí, ve kterém jsou zadány zdrojové objekty, je důležité: pozdější vlastnosti zdrojových objektů přepíší ty starší.
Vyplnění neúplného objektu výchozími hodnotami vlastností je účinná strategie, díky níž bude váš kód bezpečný a odolný. Bez ohledu na situaci objekt vždy obsahuje celou sadu vlastností: a undefined
nelze vygenerovat.
Bonusový tip: nullish coalescing
Operátor nullish coalescing vyhodnotí výchozí hodnotu, když je jeho operand undefined
nebo null
:
Nullish coalescing operator je vhodný pro přístup k vlastnosti objektu, přičemž má výchozí hodnotu, když tato vlastnost je undefined
nebo null
:
styles
objekt nemá vlastnost color
, tedy styles.color
přístupový objekt vlastnosti je undefined
. styles.color ?? "black"
se vyhodnotí na výchozí hodnotu "black"
.
styles.fontSize
je 18
, takže nulový operátor splynutí vyhodnotí hodnotu vlastnosti 18
.
2.3 Funkční parametry
Funkční parametry implicitně výchozí
undefined
.
Obvykle by měla být vyvolána funkce definovaná s konkrétním počtem parametrů se stejným počtem argumentů. Tehdy parametry získají hodnoty, které očekáváte:
When multiply(5, 3)
, parametry a
a b
přijímat 5
a 3
hodnoty. Násobení se počítá podle očekávání: 5 * 3 = 15
.
Co se stane, když vynecháte argument o vyvolání? Odpovídající parametr uvnitř funkce se stane undefined
.
Pojďme mírně upravit předchozí příklad voláním funkce pouze s jedním argumentem:
Vyvolání multiply(5)
se provádí s jediným argumentem: jako výsledek a
parametr je 5
, ale b
parametr je undefined
.
Tip 6: Použijte výchozí hodnotu parametru
Někdy funkce nevyžaduje při vyvolání úplnou sadu argumentů. U parametrů, které nemají hodnotu, můžete nastavit výchozí hodnoty.
Připomeňme si předchozí příklad, pojďme tedy vylepšit. Pokud je b
parametr undefined
, nechte jej výchozí na 2
:
Funkce je vyvolána jediným argumentem multiply(5)
. Zpočátku je a
parametr 2
a b
je undefined
.
Podmíněné prohlášení ověří, zda b
je undefined
. Pokud k tomu dojde, b = 2
přiřazení nastaví výchozí hodnotu.
I když zadaný způsob přiřazování výchozích hodnot funguje, nedoporučuji porovnávat přímo s undefined
. Je podrobný a vypadá jako hack.
Lepším přístupem je použití funkce výchozích parametrů ES2015. Je to krátké, expresivní a žádné přímé srovnání s undefined
.
Přidání výchozí hodnoty k parametru b = 2
vypadá lépe:
b = 2
v podpisu funkce zajistí, že pokud b
je undefined
, výchozí parametr je 2
.
Funkce výchozích parametrů ES2015 je intuitivní a expresivní. Vždy jej použijte k nastavení výchozích hodnot pro volitelné parametry.
2.4 Návratová hodnota funkce
Implicitně, bez příkazu
return
, funkce JavaScriptu vracíundefined
.
Funkce, která nemá return
implicitně vrátí undefined
:
square()
funkce nevrátí žádné výsledky výpočtu. Výsledkem vyvolání funkce je undefined
.
Stejná situace nastane, když je přítomen příkaz return
, ale bez výrazu v okolí:
return;
příkaz je proveden, ale nevrací žádný výraz. Výsledkem vyvolání je také undefined
.
Samozřejmě, označení poblíž return
výrazu, který má být vrácen, funguje podle očekávání:
Nyní je vyvolání funkce vyhodnoceno na 4
, což je 2
na druhou.
Tip 7: Nedůvěřujte automatickému vkládání středníků
Následující seznam příkazů v JavaScriptu musí končit středníky (;
) :
- prázdné prohlášení
-
let
,const
,var
,import
,export
prohlášení - prohlášení výrazu
-
debugger
prohlášení -
continue
prohlášení,break
prohlášení -
throw
prohlášení -
return
prohlášení
Pokud použijete-li jeden z výše uvedených příkazů, nezapomeňte na konci uvést středník:
Na konci obou let
prohlášení a return
prohlášení je zapsán povinný středník.
Co se stane, když je nechcete označovat středníky? V takové situaci poskytuje ECMAScript mechanismus automatického středníkového vkládání (ASI), který za vás vloží chybějící středníky.
S pomocí ASI můžete středníky odebrat z předchozího příkladu:
Výše uvedený text je platný kód JavaScript. Chybějící středníky se automaticky vloží.
Na první pohled to vypadá docela slibně. Mechanismus ASI umožňuje přeskočit zbytečné středníky. Můžete zmenšit a usnadnit čtení kódu JavaScript.
Existuje jedna malá, ale nepříjemná past vytvořená ASI. Když nový řádek stojí mezi return
a vráceným výrazem return \n expression
, ASI před nový řádek automaticky vloží středník return; \n expression
.
Co to znamená uvnitř funkce mít return;
prohlášení? Funkce vrátí undefined
. Pokud neznáte podrobně mechanismus ASI, je neočekávaně vrácená undefined
zavádějící.
Podívejme se například na vrácenou hodnotu getPrimeNumbers()
vyvolání:
Mezi příkazem return
a doslovným výrazem pole existuje nový řádek. JavaScript automaticky vloží za return
středník, který kód interpretuje takto:
Příkaz return;
umožňuje funkci getPrimeNumbers()
vrátit undefined
místo očekávaného pole.
Problém je vyřešen odstraněním nového řádku mezi return
a literárním polem:
Mým doporučením je prostudovat, jak přesně funguje automatické středníkové vložení, aby se takovým situacím zabránilo.
Samozřejmě nikdy nedávejte nový řádek mezi return
a vrácený výraz.
2.5 void operator
void <expression>
vyhodnotí výraz a vrátí undefined
bez ohledu na výsledek hodnocení.
Jedním z případů použití operátoru void
je potlačit vyhodnocení výrazu na undefined
, spoléhající se na některé vedlejší účinky hodnocení.
3. undefined in arrays
Získáte undefined
při přístupu k prvku pole s indexem out of bounds.
colors
pole má 3 prvky, takže platné indexy jsou 0
, 1
a 2
.
Protože v indexech 5
a -1
nejsou žádné prvky pole, přístupové subjekty colors
a colors
jsou undefined
.
V JavaScriptu se můžete setkat s takzvanými řídkými poli. Práce jsou pole, která mají mezery, tj. U některých indexů nejsou definovány žádné prvky.
Když je přístup k mezeře (aka prázdný slot) uvnitř řídkého pole, dostanete také undefined
.
Následující příklad generuje řídká pole a pokouší se získat přístup k jejich prázdným slotům:
sparse1
je vytvořen vyvoláním Array
konstruktor s prvním numerickým argumentem.Má 3 prázdné sloty.
sparse2
je vytvořen s literálem pole s chybějícím druhým prvkem.
V kterémkoli z těchto řídkých polí s přístupem k prázdnému slotu se vyhodnotí undefined
.
Při práci s poli, abyste se vyhnuli undefined
, použijte platné indexy polí a zabraňte vytváření řídkých polí.
4. Rozdíl mezi nedefinovanými a nulovými
Jaký je hlavní rozdíl mezi undefined
a null
? Obě speciální hodnoty znamenají prázdný stav.
undefined
představuje hodnotu proměnné, která ještě nebyla inicializována, zatímconull
představuje záměrnou nepřítomnost objektu.
Podívejme se na rozdíl v některých příkladech.
Je definována proměnná number
, ale není přiřazena počáteční hodnota:
number
proměnná je undefined
, což označuje neinicializovanou proměnnou.
Ke stejnému neinicializovanému konceptu dochází při přístupu k vlastnosti neexistujícího objektu:
Protože lastName
neexistuje v obj
, JavaScript vyhodnotí obj.lastName
na undefined
.
Na druhé straně víte, že proměnná očekává objekt. Ale z nějakého důvodu nemůžete vytvořit instanci objektu. V takovém případě je null
smysluplným indikátorem chybějícího objektu.
Například clone()
je funkce, která klonuje prostý objekt JavaScriptu. Očekává se, že funkce vrátí objekt:
Nicméně clone()
může být vyvolán s bezobjektovým argumentem: 15
nebo null
. V takovém případě funkce nemůže vytvořit klon, takže vrátí null
– indikátor chybějícího objektu.
typeof
operátor rozlišuje mezi undefined
a null
:
Také přísný operátor kvality ===
správně rozlišuje undefined
from null
:
5. Závěr
undefined
existence je důsledkem permisivní povahy JavaScriptu, která umožňuje použití:
- neinicializovaných proměnných
- neexistující vlastnosti nebo metody objektu
- mimo hranice indexů pro přístup k prvkům pole
- výsledek vyvolání funkce, která nic nevrací
Porovnávání přímo s undefined
je nebezpečné, protože se spoléháte na povolený, ale odrazený postup uvedený výše.
Účinnou strategií je snížit minimálně vzhled klíčového slova undefined
v kódu pomocí dobrých návyků, jako jsou:
- omezit využití neinicializovaných proměnných
- zkrátit životní cyklus proměnných a přiblížit se zdroji jejich použití
- kdykoli je to možné, přiřadit proměnným počáteční hodnoty
- upřednostňovat
const
, jinak použijtelet
- použít výchozí hodnoty pro nevýznamné funkční parametry
- ověřit vlastnosti existence nebo naplnění nebezpečných objektů výchozími vlastnostmi
- nepoužívejte řídká pole
Je dobré, že JavaScript obsahuje undefined
a null
, které představují prázdné hodnoty?