Cum să obțineți tipul de date precis al unei variabile în JavaScript

Introducere

Una dintre cele mai controversate caracteristici de limbă JavaScript este tastarea sa moale sau dinamică a căreia am vorbit deja ocazional. Aceasta înseamnă că, spre deosebire de alte limbi clasice, cum ar fi C sau Java, când declarăm variabile, nu avem nevoie să specificăm tipul de date pe care îl vor conține. Mai mult, aceeași variabilă, poate avea mai multe tipuri diferite în diferite momente de execuție: poate începe să fie un întreg, să devină o matrice și mai târziu, de exemplu, se termină să fie un obiect.

Această flexibilitate are Avantaje foarte interesante pentru dezvoltarea de aplicații complexe, deoarece nu există limitări priori cu privire la ceea ce o variabilă poate stoca. Cu toate acestea, pentru cei care provin din alte limbi dur, una dintre problemele acestui concept este că este foarte dificil să se identifice tipul de date specific pe care o variabilă are la un moment dat de execuție.

H2> Identificarea Tipul

În mod eficient, JavaScript nu posedă un mijloc univoc pentru a identifica tipul de date care conține o variabilă la un moment dat. Nativ, avem două instrucțiuni care ne pot oferi o valoare aproximativă, dar, din păcate, nu sunt finale: Tipul și instanța.

Operatorul de tip

Typeof este un operator UNAR, ce ceea ce înseamnă că el acceptă doar (și operează) pe un singur argument; În acest caz o variabilă:

 Tipul 2; // Numpthpeof "Hello World '// Stringtypeof // Obiect 

Acest operator nu este o funcție; Cu toate acestea, parantezele pot fi utilizate pentru a grupa termenii care urmează să fie evaluați:

 Tipul (2); // Nubertypeof ("Bună ziua"); // stringtypeof ("foo", 4); // Număr 

Notă: Grupurile de argumentare din JavaScript determină valoarea finală a unui element prin utilizarea operatorilor interni. Acești operatori indică ordinea în care sunt evaluați termenii, cum ar fi virgula, ceea ce face ca această evaluare să fie lăsată la stânga la dreapta pentru a returna valoarea celui de-al doilea operand. Pentru mai multe informații despre acest aspect de limbă, este recomandat un operator de virgulă JavaScript.

Tabelul următor arată corespondența obiectelor JavaScript și valoarea obținută cu Typef:

rezultat
„nedefinit”
null „obiect”
boolean „boolean”
numărul „Număr”
„șir”
obiect gazdă (în interiorul JS Mediu) Depinde de implementarea
obiect xml e4x „xml”
xmllist e4x „xml”
Orice obiect „obiect

Cum putem vedea , Nu există nicio referință în tabel înainte de elemente cum ar fi matrice, date, expresii regulate etc. Aceasta înseamnă că pentru TypeOf, aceste elemente sunt un obiect mai mult. În plus, vedem câteva rezultate care pot părea confuze ca nul în care ajungem ca un tip de „obiect” nou:

iv id = „b0d997f203”

 Tipul Nan; // Nubertypeof Infinity; // nubertypeof (1/0); // nubertypeof (TYPEF); // string 

Se pare că nu putem avea încredere în acest operator prea mult pentru a determina tipul de date pe care le-am evaluat, astfel încât ar putea fi interesant să căutați o altă siguranță sau mai completă Soluție.

obiect.protype.string

funcția de tostring, returnează un șir care reprezintă obiectul indicat ca argument:

div id = „6CEC4A2976”>

obiect.protype.tring (); //

Să vedem rezultatul: „”: Potrivit specificației ECMAScript5, obiecte.protype.String Returnează ca rezultat concatenarea lanțului „obiect” plus Valoarea internă a obiectului Ce este trecut (ceea ce numim clasa de clasă) …

]

Toate obiectele JavaScript au un proprietar intern cunoscut sub numele de] (Notația cu Double Clasp este aceeași cu cea utilizată în specificația ES5). Potrivit Es5,] este un lanț cu o singură valoare (non-editabilă) care identifică fiecare obiect. Prin urmare, un obiect invocat cu constructorul și care nu a fost modificat, returnează ca valoare a acestei proprietăți tipul de obiect precis la care aparține:

iv id = „b0d997f203”

 var o = obiect nou (); sau.a intepa (); // pre> 

Cu toate acestea, vedem că acest operator este, de asemenea, fragil atunci când îl aplicăm pe obiecte comune:

iv id = "b0d997f203"
. (); // "foo, bar, 1" "Bună ziua" .Tostring (); // "Hello World" /a-z/.testring (); // / A-Z / "

Aceasta este așa, deoarece obiectele personalizate suprascrieți obiectul.protype.String metoda cu propria dvs. O modalitate de a rezolva acest lucru este de a invoca această metodă direct din obiectul obiectului și de a utiliza funcția de apel pentru a injecta argumentul dorit:

 obiect.prototype.tring.call (); // obiecte.protype.toscall ("Bună ziua"); // obiecte.protype.tring.call (/ a-z /); // 

În acest mod, evităm suprascrisătatea și rezultatul obținut este de așteptat: avem tipul corect de date.

Crearea unei funcții la Determinați tipul de date

extras direct de la articolul Angus Croll, putem folosi următoarea funcție pentru a obține tipul corect de date de variabilă sau obiect:

 var type = funcția (obj) {retur ({}). tostring.call (obj) .match (/ s (+) /) . Tolowowercase ()} 

Să o examinăm în părți:

  • ({}). Tostring este o abreviere (o comandă rapidă) a obiectului .Protype. Puiring Deoarece, în orice obiect nou, metoda de tostring se referă la definirea dată de obiecte.protype așa cum am văzut mai sus.
  • sunați o folosim aici, astfel încât metoda anterioară să fie făcută pe argument că indicăm, în acest caz, un alt obiect.
  • Match: Folosim o expresie regulată pentru a extrage tipul de date fără caden La „obiect” inițial și paranteze. Folosim o expresie regulată în loc de o felie sau altă metodă datorită celei mai bune performanțe pe care le oferă peste restul.
  • Tolowowercase: Facem minusculă pentru a diferenția tipul de ceea ce ar fi referire la instanță de la Un obiect și că, de obicei, este majusculă.

hai să vedem cum se comportă funcția:

div id = „b0d997f203”>

 Totype ({A: 4}); // "obiect" totype (); // "matrice" (funcția () {Console.log (Totype (argumente))); // argumentstototype (New ReferenceError); // "eroare" Totype (nouă dată); // "data" Totype (/ A-Z /); // "regexp" totype (matematică); // "matematica" Totype (JSON); // "json" totype (număr nou (4)); // "număr" Totype (șir nou ("ABC"); // "șir" Totype (New Boolean (adevărat)); // "Boolean" 

și să le comparăm cu ceea ce am obține cu TypeOf:

 Tipul {A: 4}; // "obiect" Typef; // "obiect" (funcție () {console.log (argumente tipo)}) (); // ObiectivTyPeof New ReferenceRError; // "obiect" Data noului "; // "obiect" tipof / a-z /; // "obiectul" de matematică; // "obiect" Typerof JSON; // "obiect" un număr nou (4); // "obiect" un șir nou ("abc"); // "obiect" Typerof New Boolean (adevărat); // "obiect" 

Diferența în majoritatea cazurilor este importantă: de la imprecizia tipoului am continuat să obținem anumite tipuri.

Comparație cu instanța de instanță

Operatorul instanței verifică șirul prototip al primului operand care solicită prezența proprietății prototipice a celei de-a doua, care este de așteptat să corespundă cu un constructor:

 noua dată Data instanței; // matrice de instanțe adevărate; // Adevărat 

Problema acestui operator este că unele obiecte din JavaScript nu au asociate constructorului, astfel încât acestea să nu poată fi evaluate corect de exemplu:

 Matematică Instanță Math // TypeError 

Există, de asemenea, problema Din medii cu mai multe cadre în care prezența mai multor contexte globale (una pentru fiecare cadru) împiedică asigurarea faptului că un obiect dat este o instanță a unui anumit constructor:

iv id = „b0d997f203”

 var iframe = document.creelemente ("iframe"); document.body.appendordild (iframe); var iframearray = fereastră.frames.array; var array = nou iframearray (); Matrice de instanțe de array; // instanța falsă a iFramearray; // Adevărat; 

Limitări

Funcția Totype nu poate fi împiedicată de erori împotriva tipurilor de date necunoscute:

DIV ID = „B0D997F203 „>

 obiect.totip (FFF); // ReferenceRror 

În mod specific, este apelul către Totype care lansează eroarea, nu funcția în sine. Singura modalitate de a preveni acest lucru ar folosi comparația implicită care ne permite sistemul JavaScript de scurtcircuit:

 fereastră.FFF iv id = "7438951559" 

& obiect.Totype (FFF);

Dacă prima condiție este îndeplinită, următorul este continuat; În caz contrar, circuitul este tăiat și eroarea este evitată.

Concluzie

în javacript, nu putem determina cu exactitate tipul de date ale unei variabile utilizând metodele native pe care le oferă limba el însuși. De obicei, când trebuie să identificăm tipurile, de obicei vom recurge la tehnici aproximative, cum ar fi tastarea de rață. Cu toate acestea, în aplicațiile în care integritatea este critică, această tehnică nu permite ca rigoarea necesară.

Atât tipul, cât și instanța nu oferă un control riguros, fiabil și univoc asupra tipurilor pe care le-am putut avea nevoie în timpul unei dezvoltări. Pentru a încerca să rezolve această lipsă, folosim unele dintre particularitățile limbajului, cum ar fi valoarea], pentru a obține un rezultat mult mai precis.

Acest articol este o traducere extinsă a originalului Angus Croll: Fixarea JavaScript TypeOf operator.

Lasă un răspuns

Adresa ta de email nu va fi publicată. Câmpurile obligatorii sunt marcate cu *