7 sfaturi de tratat nedefinite în JavaScript
Majoritatea limbajelor moderne precum Ruby, Python sau Java au o singură valoare nulă (nil
sau null
), ceea ce pare o abordare rezonabilă.
Dar JavaScript este diferit.
null
, dar și undefined
, reprezintă în JavaScript valori goale. Deci, care este diferența exactă între ele?
Răspunsul scurt este că interpretorul JavaScript returnează undefined
atunci când accesează o variabilă sau un obiect care nu este încă inițializat. De exemplu:
Pe de altă parte, null
reprezintă un obiect lipsă referinţă. JavaScript nu inițializează variabile sau proprietăți de obiect cu null
.
Unele metode native precum String.prototype.match()
pot returna null
pentru a indica un obiect lipsă. Aruncați o privire asupra eșantionului:
Deoarece JavaScript este permisiv, dezvoltatorii au tentația de a accesa valori neinițializate. Și eu sunt vinovat de o astfel de practică proastă.
Adesea, astfel de acțiuni riscante generează undefined
erori legate:
-
TypeError: "undefined" is not a function
-
TypeError: Cannot read property "<prop-name>" of undefined
- și erori de tip asemănător.
Dezvoltatorul JavaScript poate înțelege ironia acestei glume :
Pentru a reduce astfel de erori, trebuie să înțelegeți cazurile în care undefined
este generat. Să explorăm undefined
și efectul său asupra siguranței codului.
1. Ce este nedefinit
JavaScript are 6 tipuri primitive:
Și un tip de obiect separat: {name: "Dmitri"}
, .
Din 6 tipuri primitive undefined
este o valoare specială cu propriul tip Nedefinit. Conform specificațiilor ECMAScript:
Valoarea primitivă nedefinită este utilizată atunci când unei variabile nu i s-a atribuit o valoare.
Standardul definește clar că veți primi undefined
atunci când accesați variabile neinițializate, proprietăți de obiect inexistente, elemente de matrice inexistente și deopotrivă.
Câteva exemple:
Exemplul de mai sus demonstrează că accesarea:
- unei variabile neinicializate
number
- o proprietate de obiect inexistentă
movie.year
- sau un element de matrice inexistent
movies
sunt evaluate la undefined
.
Specificația ECMAScript definește tipul de valoare undefined
:
Tipul nedefinit este un tip a cărui singură valoare este
undefined
valoarea.
În acest sens, typeof
operator returnează "undefined"
șir pentru o valoare undefined
:
Desigur, typeof
funcționează frumos pentru a verifica dacă o variabilă conține o valoare undefined
:
2. Scenarii care creează nedefinit
2.1 Variabilă neinițializată
O variabilă declarată, dar care nu este încă atribuită cu o valoare (neinitializată) este implicit
undefined
.
Simplu și simplu:
myVariable
este declarat și nu este încă atribuit cu o valoare. Accesarea variabilei se evaluează la undefined
.
O abordare eficientă pentru a rezolva problemele variabilelor neinițializate este ori de câte ori este posibil să atribuiți o valoare inițială. Cu cât variabila există mai puțin într-o stare neinițială, cu atât mai bine.
În mod ideal, ați atribui o valoare imediat după declarație const myVariable = "Initial value"
. Dar acest lucru nu este întotdeauna posibil.
Sfat 1: Favorizați const
, altfel folosiți let
, dar spuneți adio var
În opinia mea, una dintre cele mai bune caracteristici ale ECMAScript 2015 este noua modalitate de a declara variabile folosind const
și let
. Este un mare pas înainte.
const
și let
sunt cuprinse în blocuri (contrar funcției mai vechi cuprinse în var
) și există într-o zonă moartă temporală până la linia declarației.
Recomand variabila const
atunci când valoarea acesteia nu se va schimba. Creează o legătură imuabilă.
Una dintre caracteristicile frumoase ale const
este că trebuie să atribuiți o valoare inițială variabilei const myVariable = "initial"
. Variabila nu este expusă stării neinițializate și accesul la undefined
este imposibil.
Să verificăm funcția care verifică dacă un cuvânt este un palindrom:
length
și half
variabilele sunt atribuite cu o valoare o singură dată. Pare rezonabil să le declarăm ca const
, deoarece aceste variabile nu se vor schimba.
Utilizați declarația let
pentru variabilele a căror valoare se poate modifica. Ori de câte ori este posibil, atribuiți imediat o valoare inițială, de ex. let index = 0
.
Dar școala veche var
? Sugestia mea este să încetezi să o folosești.
var
problema declarației este ridicarea variabilă în domeniul funcției. Puteți declara o variabilă var
undeva la sfârșitul domeniului funcției, dar totuși o puteți accesa înainte de declarație și veți primi un undefined
.
myVariable
este accesibil și conține undefined
chiar înainte de linia de declarație: var myVariable = "Initial value"
.
Contrar, o variabilă const
sau let
nu poate fi accesată înainte de linia de declarație – variabila se află într-o zonă moartă temporală înainte de declarație. Și asta e frumos, deoarece aveți mai puține șanse să accesați un undefined
.
Exemplul de mai sus actualizat cu let
(în schimb din var
) aruncă un ReferenceError
deoarece variabila din zona moartă temporală nu este accesibilă.
Încurajarea utilizării const
pentru legături imuabile sau let
în caz contrar, asigură o practică care reduce aspectul celor neinițializați variabil.
Sfat 2: Creșteți coeziunea
Coeziunea caracterizează gradul în care elementele unui modul (spațiu de nume, clasă, metodă, bloc de cod) aparțin împreună. Coeziunea poate fi mare sau scăzută.
Este preferabil un modul cu coeziune ridicată, deoarece elementele unui astfel de modul se concentrează doar pe o singură sarcină. Face modulul:
- Concentrat și ușor de înțeles: mai ușor de înțeles ce face modulul
- Mentenabil și mai ușor de refactorizat: schimbarea modulului afectează mai puține module
- Reutilizabil: fiind concentrat pe o singură sarcină, face modulul mai ușor de reutilizat
- Testabil: ați testa mai ușor un modul care se concentrează pe o singură sarcină
Coeziunea ridicată însoțită de cuplaje libere este caracteristica unui sistem bine conceput.
Un bloc de cod poate fi considerat un modul mic. Pentru a profita de beneficiile coeziunii ridicate, păstrați variabilele cât mai aproape posibil de blocul de cod care le folosește.
De exemplu, dacă o variabilă există doar pentru a forma logica sferei de blocare, atunci declarați și faceți variabila vie doar în acel bloc (folosind const
sau let
declarații). Nu expuneți această variabilă scopului blocului exterior, deoarece blocului exterior nu ar trebui să îi pese de această variabilă.
Un exemplu clasic al duratei de viață extinse inutil a variabilelor este utilizarea for
ciclu în interiorul unei funcții:
index
, item
și sunt declarate la începutul corpului funcției. Cu toate acestea, ele sunt folosite doar aproape de final. Care este problema cu această abordare?
Între declarația din partea de sus și utilizarea în instrucțiunea for
variabilele index
, item
sunt neinițializate și expuse la undefined
. Au un ciclu de viață nerezonabil de lung în întreaga funcție.
O abordare mai bună este mutarea acestor variabile cât mai aproape posibil de locul de utilizare:
index
și item
variabilele există numai în domeniul de aplicare al blocului declarației for
. Nu au nicio semnificație în afara for
.
length
variabila este declarată și aproape de sursa de utilizare a acesteia.
De ce versiunea modificată este mai bună decât cea inițială? Să vedem:
- Variabilele nu sunt expuse unei stări neinitializate, deci nu aveți niciun risc să accesați
undefined
- Mutarea variabilele cât mai aproape posibil de locul lor de utilizare măresc lizibilitatea codului
- Bucăți de cod foarte coezive sunt mai ușor de refactorizat și extras în funcții separate, dacă este necesar
2.2 Accesarea o proprietate inexistentă
Când accesați o proprietate obiect inexistentă, JavaScript returnează
undefined
.
Să demonstrăm că într-un exemplu:
favoriteMovie
este un obiect cu o singură proprietate title
. Accesarea unei proprietăți inexistente actors
utilizând un accesor de proprietate favoriteMovie.actors
se evaluează la undefined
.
Accesarea unei proprietăți inexistente nu generează o eroare. Problema apare atunci când se încearcă obținerea de date din proprietatea inexistentă, care este cea mai comună capcană undefined
, reflectată în binecunoscutul mesaj de eroare TypeError: Cannot read property <prop> of undefined
.
Să modificăm ușor fragmentul de cod anterior pentru a ilustra o aruncare TypeError
:
favoriteMovie
nu are proprietatea actors
, deci favoriteMovie.actors
evaluează la undefined
.
Ca rezultat, accesarea primului element al unei valori undefined
utilizând expresia favoriteMovie.actors
aruncă un TypeError
.
Natura permisivă a JavaScript-ului care permite accesarea proprietăților inexistente este o sursă de nedeterminism: proprietatea poate fi setată sau nu. Modul bun de a ocoli această problemă este de a restricționa obiectul să fi definit întotdeauna proprietățile pe care le deține.
Din păcate, de multe ori nu aveți control asupra obiectelor. Astfel de obiecte pot avea un set diferit de proprietăți în diverse scenarii. Deci, trebuie să gestionați manual toate aceste scenarii.
Să implementăm o funcție append(array, toAppend)
care se adaugă la începutul și / sau la sfârșitul unui set de elemente noi. Parametrul toAppend
acceptă un obiect cu proprietăți:
-
first
: element inserat la începutularray
-
last
: element inserat la sfârșitularray
.
Funcția returnează o nouă instanță de matrice, fără a modifica matricea originală.
Prima versiune a append()
, puțin naivă, poate arăta astfel:
Deoarece toAppend
obiectul poate omite proprietățile first
sau last
, este obligatoriu să verificați dacă aceste proprietăți există în toAppend
.
Un accesor de proprietate evaluează la undefined
dacă proprietatea nu există. Prima tentație de a verifica dacă sunt prezente proprietățile first
sau last
este de a le verifica împotriva undefined
. Acest lucru se realizează în condiționare if(toAppend.first){}
și if(toAppend.last){}
…
Nu atât de rapid. Această abordare are un dezavantaj. undefined
, precum și false
, null
, 0
, NaN
și ""
sunt valori false.
În implementarea curentă a append()
, funcția nu permite inserarea de elemente false:
Sfaturile care urmează explică modul de verificare corectă a existenței proprietății.
Sfat 3: Verificați existența proprietății
Din fericire, JavaScript oferă o grămadă de moduri de a determina dacă obiectul are o proprietate specifică:
-
obj.prop !== undefined
: comparați cuundefined
direct -
typeof obj.prop !== "undefined"
: verificați tipul de valoare al proprietății -
obj.hasOwnProperty("prop")
: verificați dacă obiectul are o proprietate proprie -
"prop" in obj
: verificați dacă obiectul are o proprietate proprie sau moștenită
Recomandarea mea este să utilizați operatorul in
. Are o sintaxă scurtă și dulce. in
prezența operatorului sugerează o intenție clară de a verifica dacă un obiect are o proprietate specifică, fără a accesa valoarea reală a proprietății.
obj.hasOwnProperty("prop")
este și o soluție plăcută. Este puțin mai lung decât operatorul in
și verifică numai în proprietățile proprii ale obiectului.
Să îmbunătățim funcția append(array, toAppend)
folosind operatorul in
:
"first" in toAppend
(și "last" in toAppend
) este true
indiferent dacă există proprietatea corespunzătoare, false
altfel.
in
operatorul remediază problema cu inserarea elementelor false 0
și false
. Acum, adăugarea acestor elemente la începutul și la sfârșitul lui produce rezultatul așteptat
.
Sfat 4: Destructurarea pentru a accesa proprietățile obiectului
Când accesați o proprietate obiect, uneori este necesar să setați o valoare implicită dacă proprietatea nu există.
S-ar putea să utilizați in
însoțit de operator ternar pentru a realiza acest lucru:
Sintaxa operatorului ternar devine descurajantă când crește numărul de proprietăți de verificat. Pentru fiecare proprietate, trebuie să creați o nouă linie de cod pentru a gestiona valorile implicite, crescând un perete urât de operatori ternari cu aspect similar.
Pentru a folosi o abordare mai elegantă, să ne familiarizăm cu o funcție excelentă ES2015 numită destructurare a obiectelor.
Destructurarea obiectelor permite extragerea în linie a valorilor proprietății obiectului direct în variabile și setarea unei valori implicite dacă proprietatea nu există. O sintaxă convenabilă pentru a evita tratarea directă cu undefined
.
Într-adevăr, extragerea proprietății este acum precisă:
Pentru a vedea lucrurile în acțiune, să definim o funcție utilă care înfășoară un șir între ghilimele.
quote(subject, config)
acceptă primul argument ca șir de înfășurat. Al doilea argument config
este un obiect cu proprietățile:
Aplicând beneficiile destructurării obiectului, să implementăm quote()
:
const { char = """, skipIfQuoted = true } = config
atribuirea de destructurare într-o singură linie extrage proprietățile char
și skipIfQuoted
din obiectul config
.
Dacă lipsesc unele proprietăți în obiectul config
, atribuirea de destructurare setează valorile implicite : """
pentru char
și false
pentru skipIfQuoted
.
Din fericire, funcția mai are loc de îmbunătățit.
Să mutăm atribuirea de destructurare în secțiunea de parametri. Și setați o valoare implicită (un obiect gol { }
) pentru parametrul config
, pentru a omite al doilea argument când sunt suficiente setările implicite.
Atribuirea de destructurare înlocuiește parametrul config
din semnătura funcției. Îmi place asta: quote()
devine cu o linie mai scurtă.
= {}
în partea dreaptă a atribuirii de destructurare asigură utilizarea unui obiect gol dacă al doilea argument nu este deloc specificat quote("Sunny day")
.
Destructurarea obiectelor este o caracteristică puternică care gestionează eficient extragerea proprietăților din obiecte. Îmi place posibilitatea de a specifica o valoare implicită care trebuie returnată atunci când proprietatea accesată nu există. Ca urmare, evitați undefined
și bătăile din jurul său.
Sfatul 5: Umpleți obiectul cu proprietăți implicite
Dacă nu este nevoie să creați variabile pentru fiecare proprietate, așa cum face și atribuirea de destructurare, obiectul care nu are în vedere anumite proprietăți poate fi completat cu valori implicite.
ES2015 Object.assign(target, source1, source2, ...)
copiază valorile tuturor proprietăților proprii enumerabile de la unul sau mai multe obiecte sursă în obiectul țintă. Funcția returnează obiectul țintă.
De exemplu, trebuie să accesați proprietățile obiectului unsafeOptions
care nu conține întotdeauna setul său complet de proprietăți.
Pentru a evita undefined
atunci când accesați o proprietate inexistentă din unsafeOptions
, să facem câteva ajustări:
- Definiți un obiect
defaults
care deține valorile implicite ale proprietății - Apelați
Object.assign({ }, defaults, unsafeOptions)
un obiect nouoptions
. Noul obiect primește toate proprietățile de launsafeOptions
, dar cele lipsă sunt preluate de ladefaults
.
unsafeOptions
conține numai proprietatea fontSize
. Obiectul defaults
definește valorile implicite pentru proprietățile fontSize
și color
.
Object.assign()
ia primul argument ca obiect țintă {}
. Obiectul țintă primește valoarea fontSize
proprietate de la unsafeOptions
obiect sursă. Și valoarea color
proprietate de la defaults
obiect sursă, deoarece unsafeOptions
nu conține color
.
Contează ordinea în care sunt enumerate obiectele sursă: proprietățile obiectelor sursă ulterioare le suprascriu pe cele anterioare.
Acum puteți accesa în siguranță orice proprietate a obiectului options
, inclusiv options.color
care nu era disponibil în unsafeOptions
inițial.
Din fericire, există o alternativă mai ușoară pentru a umple obiectul cu proprietăți implicite.Vă recomand să utilizați proprietățile de răspândire în inițializatoarele de obiecte.
În loc de invocare Object.assign()
, utilizați sintaxa răspândirii obiectelor pentru a copia în obiectul țintă toate proprietățile proprii și enumerabile din obiectele sursă:
inițializatorul de obiecte răspândește proprietăți din defaults
și unsafeOptions
obiecte sursă. Ordinea în care sunt specificate obiectele sursă este importantă: proprietățile ulterioare ale obiectului sursă le suprascriu pe cele anterioare.
Completarea unui obiect incomplet cu valorile implicite ale proprietății este o strategie eficientă pentru a vă face codul sigur și durabil. Indiferent de situație, obiectul conține întotdeauna setul complet de proprietăți: și undefined
nu poate fi generat.
Sfat bonus: coalescere nulă
Operatorul coalescent nul evaluează o valoare implicită atunci când operandul său este undefined
sau null
:
Operatorul de coalescență nul este convenabil pentru a accesa o proprietate obiect în timp ce are o valoare implicită atunci când această proprietate este undefined
sau null
:
styles
obiectul nu are proprietatea color
, deci styles.color
accesorul proprietății este undefined
. styles.color ?? "black"
evaluează valoarea implicită "black"
.
styles.fontSize
este 18
, astfel încât operatorul de coalescență nul evaluează valoarea proprietății 18
.
2.3 Parametrii funcției
Parametrii funcției implicit impliciți la
undefined
.
De obicei, o funcție definită cu un număr specific de parametri ar trebui invocată cu același număr de argumente. Atunci parametrii obțin valorile pe care le așteptați:
Când multiply(5, 3)
, parametrii a
și b
primesc 5
și respectiv 3
valori. Înmulțirea este calculată conform așteptărilor: 5 * 3 = 15
.
Ce se întâmplă atunci când omiteți un argument privind invocarea? Parametrul corespunzător din interiorul funcției devine undefined
.
Să modificăm ușor exemplul anterior apelând funcția cu un singur argument:
Invocarea multiply(5)
se efectuează cu un singur argument: ca rezultat a
parametrul este 5
, dar Parametrul b
este undefined
.
Sfat 6: utilizați valoarea parametrului implicit
Uneori o funcție nu necesită setul complet de argumente la invocare. Puteți seta valori implicite pentru parametrii care nu au o valoare.
Reamintind exemplul anterior, să facem o îmbunătățire. Dacă parametrul b
este undefined
, lăsați-l implicit la 2
:
Funcția este invocată cu un singur argument multiply(5)
. Inițial, parametrul a
este 2
și b
este undefined
.
Declarația condițională verifică dacă b
este undefined
. Dacă se întâmplă, atribuirea b = 2
setează o valoare implicită.
În timp ce modul furnizat de atribuire a valorilor implicite funcționează, nu vă recomand să comparați direct cu undefined
. Este detaliat și arată ca un hack.
O abordare mai bună este utilizarea caracteristicii parametrilor impliciti ES2015. Este scurt, expresiv și nu are comparații directe cu undefined
.
Adăugarea unei valori implicite la parametrul b = 2
arată mai bine:
b = 2
în semnătura funcției asigură că, dacă b
este undefined
, parametrul implicit este 2
.
Parametrii prestabiliti ES2015 sunt intuitivi și expresivi. Folosiți-l întotdeauna pentru a seta valorile implicite pentru parametrii opționali.
2.4 Valoarea returnată a funcției
Implicit, fără instrucțiunea
return
, o funcție JavaScript returneazăundefined
.
O funcție care nu are return
implicit returnează undefined
:
nu returnează niciun rezultat de calcul. Rezultatul invocării funcției este undefined
.
Aceeași situație se întâmplă atunci când este prezentă declarația return
, dar fără o expresie în apropiere:
return;
este executată, dar nu returnează nicio expresie. Rezultatul invocării este, de asemenea, undefined
.
Desigur, indicând lângă return
expresia care trebuie returnată funcționează conform așteptărilor:
Acum, invocarea funcției este evaluată la 4
, care este 2
pătrat.
Sfat 7: Nu aveți încredere în inserarea automată de punct și virgulă
Următoarea listă de instrucțiuni din JavaScript trebuie să se încheie cu punct și virgulă (;
) :
- declarație goală
-
let
,const
,var
,import
,export
declarații - declarație de expresie
-
debugger
declarație -
continue
declarație,break
declarație -
throw
declarație -
return
declarație
Dacă folosiți una dintre afirmațiile de mai sus, asigurați-vă că indicați un punct și virgulă la sfârșit:
La sfârșitul ambelor let
declarație și declarație return
se scrie un punct și virgul obligatoriu.
Ce se întâmplă atunci când nu doriți să indicați aceste punct si virgula? Într-o astfel de situație, ECMAScript oferă un mecanism de inserare automată de punct și virgulă (ASI), care introduce pentru dvs. punctele și virgulele lipsă.
Ajutat de ASI, puteți elimina punctele și virgulele din exemplul anterior:
Textul de mai sus este un cod JavaScript valid. Punctele și virgulele lipsă sunt inserate automat pentru dvs.
La prima vedere, pare destul de promițător. Mecanismul ASI vă permite să săriți punctele și virgulele inutile. Puteți face codul JavaScript mai mic și mai ușor de citit.
Există o capcană mică, dar enervantă creată de ASI. Când o linie nouă se află între return
și expresia returnată return \n expression
, ASI introduce automat un punct și virgulă înainte de linia nouă return; \n expression
.
Ce înseamnă în interiorul unei funcții să ai o instrucțiune return;
? Funcția returnează undefined
. Dacă nu cunoașteți în detaliu mecanismul ASI, undefined
returnat în mod neașteptat este înșelător.
De exemplu, să studiem valoarea returnată a invocării getPrimeNumbers()
:
Între instrucțiunea return
și expresia literală matrice există o nouă linie. JavaScript introduce automat un punct și virgulă după return
, interpretând codul după cum urmează:
Instrucțiunea return;
face ca funcția getPrimeNumbers()
să returneze undefined
în locul matricei așteptate.
Problema este rezolvată eliminând linia nouă între return
și literalul matricei:
Recomandarea mea este de a studia modul în care funcționează exact inserarea automată de punct și virgulă pentru a evita astfel de situații.
Desigur, nu puneți niciodată o linie nouă între return
și expresia returnată.
2.5 void operator
void <expression>
evaluează expresia și returnează undefined
indiferent de rezultat a evaluării.
Un caz de utilizare al operatorului void
este de a suprima evaluarea expresiei la undefined
, bazându-se pe un efect secundar al evaluării.
3. nedefinit în tablouri
Veți obține undefined
atunci când accesați un element de matrice cu un index în afara limitelor.
colors
matricea are 3 elemente, astfel indexurile valide sunt 0
, 1
și 2
.
Deoarece nu există elemente matrice la indexuri 5
și -1
, accesorii colors
și colors
sunt undefined
.
În JavaScript, puteți întâlni așa-numitele tablouri rare. Tezele sunt matrici care au lacune, adică la unii indici nu sunt definite elemente.
Când un spațiu (alias slot gol) este accesat în interiorul unui tablou rar, primiți și un undefined
.
Următorul exemplu generează tablouri rare și încearcă să acceseze sloturile lor goale:
sparse1
este creat prin invocarea unui Array
constructor cu un prim argument numeric.Are 3 sloturi goale.
sparse2
este creat cu un literal literal cu al doilea element lipsă.
În oricare dintre aceste matrice rare, accesarea unui slot gol se evaluează la undefined
.
Când lucrați cu matrici, pentru a evita undefined
, asigurați-vă că utilizați indexuri de matrice valide și preveniți crearea matricelor rare.
4. Diferența dintre nedefinit și nul
Care este diferența principală între undefined
și null
? Ambele valori speciale implică o stare goală.
undefined
reprezintă valoarea unei variabile care nu a fost încă inițializată, în timp cenull
reprezintă absența intenționată a unui obiect.
Să explorăm diferența în câteva exemple.
Variabila number
este definită cu toate acestea, nu este atribuit cu o valoare inițială:
number
este undefined
, care indică o variabilă neinițializată.
Același concept neinițializat se întâmplă atunci când se accesează o proprietate obiect inexistentă:
Deoarece lastName
proprietatea nu există în obj
, JavaScript evaluează obj.lastName
la undefined
.
Pe de altă parte, știți că o variabilă așteaptă un obiect. Dar, dintr-un anumit motiv, nu puteți instanția obiectul. În acest caz, null
este un indicator semnificativ al unui obiect lipsă.
De exemplu, clone()
este o funcție care clonează un obiect JavaScript simplu. Funcția este de așteptat să returneze un obiect:
Cu toate acestea, clone()
poate fi invocat cu un argument non-obiect: 15
sau null
. Într-un astfel de caz, funcția nu poate crea o clonă, deci returnează null
– indicatorul unui obiect lipsă.
typeof
operatorul face distincția între undefined
și null
:
De asemenea, operatorul strict de calitate ===
diferențiază corect undefined
din null
:
5. Concluzie
undefined
existența este o consecință a naturii permisive a JavaScript-ului, care permite utilizarea următoarelor:
- variabile neinițializate
- proprietăți sau metode de obiect inexistente
- indexuri în afara limitelor pentru accesarea elementelor matricei
- rezultatul invocării unei funcții care nu returnează nimic
Compararea directă cu undefined
nu este sigură, deoarece vă bazați pe o practică permisă, dar descurajată, menționată mai sus.
O strategie eficientă este de a reduce cel puțin aspectul cuvântului cheie undefined
în codul dvs. prin aplicarea unor obiceiuri bune, cum ar fi:
- reduceți utilizarea variabilelor neinițializate
- faceți ciclul de viață al variabilelor scurt și apropiat de sursa de utilizare a acestora
- ori de câte ori este posibil atribuiți valori inițiale variabilelor
- favorizați
const
, altfel folosițilet
- utilizați valorile implicite pentru parametrii de funcție nesemnificativi
- verificați proprietățile existență sau umpleți obiectele nesigure cu proprietăți implicite
- evitați utilizarea matricelor rare
Este bine că JavaScript are atât undefined
și null
pentru a reprezenta valori goale?