7 tip til håndtering udefineret i JavaScript
De fleste moderne sprog som Ruby, Python eller Java har en enkelt nulværdi (nil
eller null
), hvilket synes at være en rimelig tilgang.
Men JavaScript er anderledes.
null
, men også undefined
, repræsenterer i JavaScript tomme værdier. Så hvad er den nøjagtige forskel mellem dem?
Det korte svar er, at JavaScript-tolk returnerer undefined
, når du får adgang til en variabel- eller objektegenskab, der endnu ikke er initialiseret. For eksempel:
På den anden side repræsenterer null
et manglende objekt reference. JavaScript initialiserer ikke variabler eller objektegenskaber med null
.
Nogle native metoder som String.prototype.match()
kan returnere null
for at betegne et manglende objekt. Se på eksemplet:
Fordi JavaScript er tilladt, har udviklere fristelsen til at få adgang til ikke-initialiserede værdier. Jeg er også skyldig i sådan dårlig praksis.
Ofte genererer sådanne risikable handlinger undefined
relaterede fejl:
-
TypeError: "undefined" is not a function
-
TypeError: Cannot read property "<prop-name>" of undefined
- og lignende typefejl.
JavaScript-udvikler kan forstå ironien i denne vittighed :
For at reducere sådanne fejl skal du forstå de tilfælde, hvor undefined
genereres. Lad os undersøge undefined
og dens virkning på kodesikkerhed.
1. Hvad der er udefineret
JavaScript har 6 primitive typer:
Og en adskilt objekttype: {name: "Dmitri"}
, .
Fra 6 primitive typer er undefined
en speciel værdi med sin egen type Udefineret. I henhold til ECMAScript-specifikation:
Udefineret værdi primitiv værdi bruges, når en variabel ikke er tildelt en værdi.
Standarden definerer klart, at du vil modtage undefined
, når du får adgang til ikke-initialiserede variabler, ikke-eksisterende objektegenskaber, ikke-eksisterende matrixelementer og lignende.
Et par eksempler:
Ovenstående eksempel viser, at adgang til:
- en uinitialiseret variabel
number
- en ikke-eksisterende objektegenskab
movie.year
- eller et ikke-eksisterende array-element
movies
evalueres til undefined
.
ECMAScript-specifikationen definerer typen undefined
værdi:
Udefineret type er en type, hvis eneste værdi er
undefined
-værdien.
I denne forstand typeof
operator returnerer "undefined"
streng for en undefined
værdi:
Selvfølgelig fungerer typeof
pænt for at kontrollere, om en variabel indeholder en undefined
-værdi:
2. Scenarier, der skaber udefineret
2.1 Ikke-initialiseret variabel
En erklæret variabel, men endnu ikke tildelt en værdi (ikke-initialiseret) er som standard
undefined
.
Almindeligt og simpelt:
myVariable
erklæres og endnu ikke tildeles en værdi. Adgang til variablen evalueres til undefined
.
En effektiv tilgang til løsning af problemer med ikke-initialiserede variabler tildeles, når det er muligt, en startværdi. Jo mindre variablen eksisterer i en uinitialiseret tilstand, jo bedre.
Ideelt set tildeler du en værdi med det samme efter erklæring const myVariable = "Initial value"
. Men det er ikke altid muligt.
Tip 1: Favorit const
, ellers brug let
, men farvel til var
Efter min mening er en af de bedste funktioner i ECMAScript 2015 den nye måde at erklære variabler ved hjælp af const
og let
. Det er et stort skridt fremad.
const
og let
er blokomfanget (i modsætning til ældre funktion scoped var
) og eksisterer i en tidsmæssig død zone indtil deklarationslinjen.
Jeg anbefaler const
variabel, når dens værdi ikke vil ændre sig. Det skaber en uforanderlig binding.
Et af de gode træk ved const
er, at du skal tildele en startværdi til variablen const myVariable = "initial"
. Variablen udsættes ikke for den ikke-initialiserede tilstand, og adgang til undefined
er umulig.
Lad os kontrollere den funktion, der verificerer, om et ord er et palindrom:
length
og half
variabler tildeles en værdi en gang. Det forekommer rimeligt at erklære dem som const
, da disse variabler ikke vil ændre sig.
Brug let
-erklæring til variabler, hvis værdi kan ændres. Når det er muligt, tildeles en startværdi med det samme, f.eks. let index = 0
.
Hvad med den gamle skole var
? Mit forslag er at stoppe med at bruge det.
var
erklæringsproblem er den variable hejsning inden for funktionsomfanget. Du kan erklære en var
variabel et sted i slutningen af funktionsomfanget, men alligevel kan du få adgang til den før erklæring: og du får en undefined
.
myVariable
er tilgængelig og indeholder undefined
allerede før erklæringslinjen: var myVariable = "Initial value"
.
I modsætning hertil er en const
eller let
variabel ikke tilgængelig før erklæringslinjen – variablen befinder sig i en tidsmæssig død zone før erklæringen. Og det er pænt, fordi du har mindre chance for at få adgang til en undefined
.
Ovenstående eksempel opdateret med let
af var
) kaster en ReferenceError
fordi variablen i den tidsmæssige døde zone ikke er tilgængelig.
Tilskyndelse til brugen af const
til uforanderlige bindinger eller let
ellers sikrer en praksis, der reducerer udseendet på de ikke-initialiserede variabel.
Tip 2: Forøg samhørighed
Samhørighed karakteriserer den grad, som elementerne i et modul (navneområde, klasse, metode, kodeblok) hører sammen. Samhørigheden kan være høj eller lav.
Et modul med høj samhørighed foretrækkes, fordi elementerne i et sådant modul kun fokuserer på en enkelt opgave. Det gør modulet:
- Fokuseret og forståeligt: lettere at forstå, hvad modulet gør
- Vedligeholdeligt og lettere at reflektere: ændringen i modulet påvirker færre moduler
- Genanvendelig: at være fokuseret på en enkelt opgave, det gør modulet lettere at genbruge
- Testbart: du ville lettere teste et modul, der er fokuseret på en enkelt opgave
Høj samhørighed ledsaget af løs kobling er karakteristikken for et veldesignet system.
En kodeblok kan betragtes som et lille modul. For at drage fordel af fordelene ved høj samhørighed skal du holde variablerne så tæt som muligt på den kodeblok, der bruger dem.
For eksempel, hvis en variabel kun eksisterer for at danne logikken for blokområdet, skal du kun erklære og gøre variablen levende inden for den blok (ved hjælp af const
eller let
erklæringer). Udsæt ikke denne variabel for det ydre blokomfang, da den ydre blok ikke burde bekymre sig om denne variabel.
Et klassisk eksempel på variablenes unødigt forlængede levetid er brugen af for
cyklus inde i en funktion:
index
, item
og length
variabler erklæres i begyndelsen af funktionslegemet. De bruges dog kun nær slutningen. Hvad er problemet med denne tilgang?
Mellem erklæringen øverst og brugen i for
udsagn variablerne index
, item
er ikke-initialiseret og udsat for undefined
. De har en urimelig lang livscyklus i hele funktionsomfanget.
En bedre tilgang er at flytte disse variabler så tæt som muligt på deres brugssted:
index
og item
variabler findes kun i blokområdet for for
udsagn. De har ingen betydning uden for for
.
length
-variablen erklæres også tæt på dens anvendelseskilde.
Hvorfor er den ændrede version bedre end den oprindelige? Lad os se:
- Variablerne udsættes ikke for uinitialiseret tilstand, så du har ingen risiko for at få adgang til
undefined
- Flytning af variabler så tæt som muligt på deres brugssted øger kodelæsbarheden
- Høje sammenhængende klumper af kode er lettere at omformulere og udtrække i separate funktioner, om nødvendigt
2.2 Adgang en ikke-eksisterende ejendom
Når du får adgang til en ikke-eksisterende objektegenskab, returnerer JavaScript
undefined
.
Lad os demonstrere det i et eksempel:
favoriteMovie
er et objekt med en enkelt egenskab title
. Adgang til en ikke-eksisterende ejendom actors
ved hjælp af en ejendomsadgang favoriteMovie.actors
evalueres til undefined
.
Adgang til en ikke-eksisterende ejendom kaster ikke en fejl. Problemet vises, når man prøver at hente data fra den ikke-eksisterende ejendom, som er den mest almindelige undefined
fælde, hvilket afspejles i den velkendte fejlmeddelelse TypeError: Cannot read property <prop> of undefined
.
Lad os ændre det forrige kodestykke lidt for at illustrere et TypeError
kast:
favoriteMovie
har ikke egenskaben actors
, så favoriteMovie.actors
evalueres til undefined
.
Som et resultat kaster adgang til det første element i en undefined
-værdi ved hjælp af udtrykket favoriteMovie.actors
et TypeError
.
Den tilladende karakter af JavaScript, der giver adgang til ikke-eksisterende ejendomme, er en kilde til ikke-bestemmelse: ejendommen kan være indstillet eller ej. Den gode måde at omgå dette problem er at begrænse objektet til altid at have defineret de egenskaber, det har.
Desværre har du ofte ikke kontrol over objekterne. Sådanne objekter kan have et andet sæt egenskaber i forskellige scenarier. Så du skal håndtere alle disse scenarier manuelt.
Lad os implementere en funktion append(array, toAppend)
, der tilføjer i begyndelsen og / eller i slutningen af en række nye elementer. toAppend
parameter accepterer et objekt med egenskaber:
-
first
: element indsat i begyndelsen afarray
-
last
: element indsat i slutningen afarray
.
Funktionen returnerer en ny matrixforekomst uden at ændre den oprindelige matrix.
Den første version af append()
, lidt naiv, kan se sådan ud:
Fordi toAppend
objekt kan udelade first
eller last
egenskaber, det er obligatorisk at kontrollere, om disse egenskaber findes i toAppend
.
En ejendomsadgang evalueres til undefined
, hvis ejendommen ikke findes. Den første fristelse til at kontrollere, om first
eller last
egenskaber er til stede, er at kontrollere dem mod undefined
. Dette udføres i betingede if(toAppend.first){}
og if(toAppend.last){}
…
Ikke så hurtigt. Denne tilgang har en ulempe. undefined
samt false
, null
, 0
, NaN
og ""
er falske værdier.
I den aktuelle implementering af append()
tillader funktionen ikke at indsætte falske elementer:
Tipene, der følger, forklarer, hvordan man korrekt kontrollerer ejendommens eksistens.
Tip 3: Kontroller ejendommens eksistens
Heldigvis tilbyder JavaScript en række måder at afgøre, om objektet har en bestemt egenskab:
-
obj.prop !== undefined
: sammenlign medundefined
direkte -
typeof obj.prop !== "undefined"
: Kontroller egenskabstypen -
obj.hasOwnProperty("prop")
: Kontroller, om objekt har en egen egenskab -
"prop" in obj
: kontroller, om objektet har en egen eller arvet ejendom
Min anbefaling er at brug operatøren in
. Det har en kort og sød syntaks. in
operatørtilstedeværelse antyder en klar hensigt om at kontrollere, om et objekt har en bestemt egenskab uden adgang til den aktuelle ejendomsværdi.
obj.hasOwnProperty("prop")
er også en god løsning. Det er lidt længere end in
-operatøren og verificerer kun i objektets egne egenskaber.
Lad os forbedre append(array, toAppend)
-funktionen ved hjælp af in
operator:
"first" in toAppend
(og "last" in toAppend
) er true
om den tilsvarende egenskab findes, false
ellers.
in
operatør løser problemet med indsættelse af falske elementer 0
og false
. Tilføjelse af disse elementer i begyndelsen og slutningen af giver nu det forventede resultat
.
Tip 4: Destrukturering for at få adgang til objektegenskaber
Når du får adgang til en objektegenskab, er det undertiden nødvendigt at indstille en standardværdi, hvis ejendommen ikke findes.
Du kan muligvis bruge in
ledsaget af ternær operatør til at opnå dette:
Ternær operatørsyntaks bliver skræmmende, når antallet af egenskaber, der skal kontrolleres, øges. For hver ejendom skal du oprette en ny linje kode for at håndtere standardindstillingerne og øge en grim mur af lignende udseende ternære operatører.
For at bruge en mere elegant tilgang, lad os blive fortrolig med en fantastisk ES2015-funktion kaldet objektdestrukturering.
Objektdestrukturering muliggør indbygget ekstraktion af objektegenskabsværdier direkte i variabler og indstilling af en standardværdi, hvis ejendommen ikke findes. En bekvem syntaks for at undgå at beskæftige sig direkte med undefined
.
Faktisk er ejendomsudvindingen nu præcis:
For at se ting i aktion, lad os definere en nyttig funktion, der omslutter en streng i anførselstegn.
quote(subject, config)
accepterer det første argument som den streng, der skal pakkes ind. Det andet argument config
er et objekt med egenskaberne:
Ved at anvende fordelene ved objektdestruktureringen, lad os implementere quote()
:
const { char = """, skipIfQuoted = true } = config
destruktionstildeling i en linje udtrækker egenskaberne char
og skipIfQuoted
fra config
-objekt.
Hvis der mangler nogle egenskaber i config
-objektet, indstiller destruktionstildelingen standardværdierne : """
til char
og false
til skipIfQuoted
.
Heldigvis har funktionen stadig plads til forbedringer.
Lad os flytte destruktionstildelingen til parameterafsnittet. Og indstil en standardværdi (et tomt objekt { }
) til config
-parameteren for at springe det andet argument over, når standardindstillingerne er tilstrækkelige.
Destruktureringsopgaven erstatter parameteren config
i funktionens signatur. Det kan jeg godt lide: quote()
bliver en linje kortere.
= {}
på højre side af destruktureringsopgaven sikrer, at et tomt objekt bruges, hvis det andet argument overhovedet ikke er angivet quote("Sunny day")
.
Objektdestrukturering er en kraftfuld funktion, der effektivt håndterer udvinding af egenskaber fra objekter. Jeg kan godt lide muligheden for at angive en standardværdi, der skal returneres, når den ejendom, der er adgang til, ikke findes. Som et resultat undgår du undefined
og besværet omkring det.
Tip 5: Fyld objektet med standardegenskaber
Hvis der ikke er behov for at oprette variabler for hver ejendom, som destruktionstildelingen gør, kan objektet, der savner nogle egenskaber, udfyldes med standardværdier.
ES2015 Object.assign(target, source1, source2, ...)
kopierer værdierne for alle enerable egne egenskaber fra et eller flere kildeobjekter til målobjektet. Funktionen returnerer målobjektet.
For eksempel skal du få adgang til egenskaberne for unsafeOptions
objekt, der ikke altid indeholder dets fulde sæt egenskaber.
For at undgå undefined
når du får adgang til en ikke-eksisterende ejendom fra unsafeOptions
, lad os foretage nogle justeringer:
- Definer et objekt
defaults
, der indeholder standardværdierne for egenskaber - Ring til
Object.assign({ }, defaults, unsafeOptions)
et nyt objektoptions
. Det nye objekt modtager alle egenskaber fraunsafeOptions
, men de manglende er taget fradefaults
.
unsafeOptions
indeholder kun fontSize
egenskab. defaults
objekt definerer standardværdierne for egenskaber fontSize
og color
.
Object.assign()
tager det første argument som et målobjekt {}
. Målobjektet modtager værdien af fontSize
ejendom fra unsafeOptions
kildeobjekt. Og værdien af color
egenskab fra defaults
kildeobjekt, fordi unsafeOptions
ikke indeholder color
.
Den rækkefølge, som kildeobjekterne tælles i, betyder noget: senere kildeobjektegenskaber overskriver tidligere.
Du er nu sikker på at få adgang til enhver ejendom af options
objekt, inklusive options.color
, der ikke var tilgængelig i unsafeOptions
oprindeligt.
Heldigvis findes der et lettere alternativ til at udfylde objektet med standardegenskaber.Jeg anbefaler at bruge spredningsegenskaberne i objektinitialiserere.
I stedet for Object.assign()
påkaldelse skal du bruge objektspredningssyntaxen til at kopiere til målobjektet alle egne og en række egenskaber fra kildeobjekter:
objekt initializer spreder egenskaber fra defaults
og unsafeOptions
kildeobjekter. Den rækkefølge, som kildeobjekterne er specificeret i, er vigtig: egenskaber for senere kildeobjekter overskriver tidligere.
Udfyldning af et ufuldstændigt objekt med standardegenskabsværdier er en effektiv strategi for at gøre din kode sikker og holdbar. Uanset situationen indeholder objektet altid det fulde sæt egenskaber: og undefined
kan ikke genereres.
Bonustip: nullish coalescing
Operatøren nullish coalescing evalueres til en standardværdi, når dens operand er undefined
eller null
:
Nullish coalescing operator er praktisk at få adgang til en objektegenskab, mens den har en standardværdi, når denne egenskab er undefined
eller null
:
styles
objekt har ikke ejendommen color
, så styles.color
ejendomsadgang er undefined
. styles.color ?? "black"
evalueres til standardværdien "black"
.
styles.fontSize
er 18
, så den nullish coalescing-operatør evaluerer til egenskabsværdien 18
.
2.3 Funktionsparametre
Funktionsparametrene er implicit standard til
undefined
.
Normalt skal en funktion defineret med et specifikt antal parametre påberåbes med det samme antal argumenter. Det er her, parametrene får de værdier, du forventer:
When multiply(5, 3)
, parametrene a
og b
modtager 5
og henholdsvis 3
værdier. Multiplikationen beregnes som forventet: 5 * 3 = 15
.
Hvad sker der, når du udelader et argument om påkaldelse? Den tilsvarende parameter inde i funktionen bliver undefined
.
Lad os ændre det foregående eksempel lidt ved at kalde funktionen med kun et argument:
Påkaldelsen multiply(5)
udføres med et enkelt argument: som resultat a
parameter er 5
b
parameter er undefined
.
Tip 6: Brug standardparameterværdi
Nogle gange kræver en funktion ikke det fulde sæt argumenter ved påkaldelse. Du kan angive standardindstillinger for parametre, der ikke har en værdi.
Når vi husker det foregående eksempel, skal vi gøre en forbedring. Hvis b
-parameteren er undefined
, skal du standardindstille den til 2
:
Funktionen påberåbes med et enkelt argument multiply(5)
. Oprindeligt er a
parameter 2
og b
er undefined
.
Den betingede erklæring verificerer, om b
er undefined
. Hvis det sker, indstiller b = 2
-tildelingen en standardværdi.
Mens den angivne måde at tildele standardværdier fungerer på, anbefaler jeg ikke at sammenligne direkte med undefined
. Det er ordentligt og ligner et hack.
En bedre tilgang er at bruge ES2015-standardparametre-funktionen. Det er kort, udtryksfuldt og ingen direkte sammenligning med undefined
.
Tilføjelse af en standardværdi til parameter b = 2
ser bedre ud:
b = 2
i funktionssignaturen sørger for at hvis b
er undefined
, parameteren er som standard 2
.
ES2015s standardparameterfunktion er intuitiv og udtryksfuld. Brug den altid til at indstille standardværdier for valgfri parametre.
2.4 Funktionsreturværdi
Implicit, uden
return
udsagn, en JavaScript-funktion returnererundefined
.
En funktion, der ikke har return
sætning returnerer implicit undefined
:
square()
-funktionen returnerer ingen beregningsresultater. Funktionsopkaldsresultatet er undefined
.
Den samme situation sker, når return
udsagn er til stede, men uden et udtryk i nærheden:
return;
udsagn udføres, men den returnerer ikke noget udtryk. Påkaldsresultatet er også undefined
.
Når det angives nær return
, fungerer det udtryk, der skal returneres, naturligvis som forventet:
Funktionsopkald evalueres til 4
, som er 2
kvadratisk.
Tip 7: Stol ikke på den automatiske indsættelse af semikolon
Følgende sætningsliste i JavaScript skal slutte med semikolon (;
) :
- tom erklæring
-
let
,const
,var
,import
,export
erklæringer - udtrykserklæring
-
debugger
udsagn -
continue
udsagn,break
udsagn -
throw
udsagn -
return
udsagn
Hvis du bruger et af ovenstående udsagn, skal du angive et semikolon i slutningen:
I slutningen af begge let
erklæring og return
udsagn der skrives et obligatorisk semikolon.
Hvad sker der, når du ikke vil angive disse semikoloner? I en sådan situation giver ECMAScript en automatisk semikolonindsættelsesmekanisme (ASI), der indsætter de manglende semikoloner til dig.
Hjælpet af ASI kan du fjerne semikolonerne fra det foregående eksempel:
Ovenstående tekst er en gyldig JavaScript-kode. De manglende semikoloner indsættes automatisk for dig.
Ved første øjekast ser det ret lovende ud. ASI-mekanismen giver dig mulighed for at springe de unødvendige semikoloner over. Du kan gøre JavaScript-koden mindre og lettere at læse.
Der er en lille, men irriterende fælde oprettet af ASI. Når en ny linje står mellem return
og det returnerede udtryk return \n expression
, indsætter ASI automatisk et semikolon før den nye linje return; \n expression
.
Hvad betyder det inde i en funktion at have return;
udsagn? Funktionen returnerer undefined
. Hvis du ikke kender i detaljer mekanismen for ASI, er den uventet returnerede undefined
vildledende.
Lad os for eksempel studere den returnerede værdi af getPrimeNumbers()
påkaldelse:
Mellem return
udsagn og arrayets bogstavelige udtryk findes en ny linje. JavaScript indsætter automatisk et semikolon efter return
og fortolker koden som følger:
Påstanden return;
gør funktionen getPrimeNumbers()
til at returnere undefined
i stedet for det forventede array.
Problemet løses ved at fjerne den nye linje mellem return
og litterær array:
Min anbefaling er at undersøge, hvordan præcis automatisk semikolonindsættelse fungerer for at undgå sådanne situationer.
Sæt naturligvis aldrig en ny linje mellem return
og det returnerede udtryk.
2,5 ugyldig operator
void <expression>
evaluerer udtrykket og returnerer undefined
uanset resultatet af evalueringen.
En brugstilfælde af void
operatør er at undertrykke ekspressionsevaluering til undefined
, afhængig af en eller anden bivirkning af evalueringen.
3. udefineret i arrays
Du får undefined
, når du får adgang til et array-element med et indeks uden for grænser.
colors
array har 3 elementer, så gyldige indekser er 0
, 1
og 2
.
Da der ikke er nogen matrixelementer ved indekser 5
og -1
, er accessorerne colors
og colors
er undefined
.
I JavaScript kan du støde på såkaldte sparsomme arrays. Specialer er arrays, der har huller, dvs. ved nogle indekser er der ikke defineret nogen elementer.
Når der åbnes et hul (også kendt som tom plads) i et sparsomt array, får du også en undefined
.
Følgende eksempel genererer sparsomme arrays og forsøger at få adgang til deres tomme slots:
sparse1
oprettes ved at påkalde en Array
konstruktør med et numerisk første argument.Den har 3 tomme slots.
sparse2
oprettes med en matrix bogstavelig med det manglende andet element.
I nogen af disse sparsomme arrays evalueres adgang til en tom plads til undefined
.
Når du arbejder med arrays, skal du sørge for at bruge gyldige array-indekser og forhindre oprettelse af sparsomme arrays for at undgå undefined
.
4. Forskel mellem udefineret og null
Hvad er den største forskel mellem undefined
og null
? Begge specielle værdier indebærer en tom tilstand.
undefined
repræsenterer værdien af en variabel, der endnu ikke er initialiseret, mensnull
repræsenterer et forsætligt fravær af et objekt.
Lad os undersøge forskellen i nogle eksempler.
Variablen number
er defineret tildeles dog ikke en startværdi:
number
variabel er undefined
, hvilket indikerer en ikke-initialiseret variabel.
Det samme uinitialiserede koncept sker, når der er adgang til en ikke-eksisterende objektegenskab:
Fordi lastName
egenskab findes ikke i obj
, JavaScript evaluerer obj.lastName
til undefined
.
På den anden side ved du, at en variabel forventer et objekt. Men af en eller anden grund kan du ikke instantiere objektet. I et sådant tilfælde er null
en meningsfuld indikator for et manglende objekt.
For eksempel er clone()
en funktion, der kloner et almindeligt JavaScript-objekt. Funktionen forventes at returnere et objekt:
Dog kan clone()
påberåbes med et ikke-objekt-argument: 15
eller null
. I et sådant tilfælde kan funktionen ikke oprette en klon, så den returnerer null
– indikatoren for et manglende objekt.
typeof
operator skelner mellem undefined
og null
:
Også den strenge kvalitetsoperator ===
skelner korrekt undefined
fra null
:
5. Konklusion
undefined
eksistens er en konsekvens af JavaScripts tilladende natur, der tillader brug af:
- ikke-initialiserede variabler
- ikke-eksisterende objektegenskaber eller -metoder
- indekser uden for grænser for at få adgang til matrixelementer
- påkaldsresultatet af en funktion, der ikke returnerer noget
At sammenligne direkte med undefined
er ikke sikkert, fordi du stoler på en tilladt, men afskrækket praksis, der er nævnt ovenfor.
En effektiv strategi er at minimere udseendet af undefined
søgeord i din kode ved at anvende gode vaner som:
- reducere brugen af ikke-initialiserede variabler
- gøre variablerne livscyklus korte og tæt på kilden til deres brug
- når det er muligt tildele startværdier til variabler
- favoriser
const
, ellers bruglet
- brug standardværdier til ubetydelige funktionsparametre
- verificer egenskaberne eksistens eller udfyld de usikre objekter med standardegenskaber
- undgå brugen af sparsomme arrays
Er det godt, at JavaScript har både undefined
og null
for at repræsentere tomme værdier?