Javascript verifică tipul unei variabile. Obțineți tipul de operator

a = (b> 0) && (c + 1! = d); pavilion =! (status = 0);

Tabelul 14.5. Operatori logici

Descrierea operatorului

! NU (inversiune logică)

&& ȘI (multiplicare logică)

|| SAU (adăugare logică)

Tabelul 14.6. Rezultatele executării operatorilor AND și OR

Operand 1

Operand 2

Tabelul 14.7. Rezultatele declarației NOT

Obțineți tipul de operator

Obțineți operator de tip typeof returnează un șir care descrie tipul de date al operandului. Operandul al cărui tip doriți să îl cunoașteți este plasat după acest operator și cuprins între paranteze:

s = typeof ("str");

Ca urmare a acestei expresii, variabila s va conține șirul „șir” care denotă tipul șirului.

Toate valorile pe care operatorul le poate returna sunt enumerate în tabel. 14.8.

Tabelul 14.8. Valorile returnate de tipul operatorului

Tipul de date

Șir restituit

Şir

Numeric

Tabelul 14.8 (sfârșit)

Tipul de date

Șir restituit

Logic

Compatibilitatea și conversia tipului de date

Acum este momentul să luăm în considerare încă două probleme importante: compatibilitatea tipului de date și conversia de la un tip la altul.

Ce se întâmplă când adăugați două numere? Așa este - încă o valoare numerică. Și dacă adăugați un număr și un șir? Este greu de spus ... Aici JavaScript se confruntă cu problema incompatibilității tipurilor de date și încearcă să facă aceste tipuri compatibile convertind unul dintre ele în altul. Mai întâi încearcă să convertească șirul într-un număr și, dacă reușește, face adăugarea. Dacă nu reușește, numărul va fi convertit într-un șir și cele două șiruri rezultate vor fi concatenate. De exemplu, executarea scriptului Web în Listarea 14.6 convertește valoarea lui b într-un tip numeric atunci când este adăugat la a; astfel, variabila c va conține valoarea 23.

Listarea 14.6

var a, b, c, d, e, f; a = 11;

b = "12"; c = a + b;

d = "JavaScript"; e = 2;

Dar din moment ce valoarea variabilei d nu poate fi convertită într-un număr, valoarea lui e va fi convertită într-un șir, iar rezultatul - valoarea lui f - va deveni

Valorile booleene sunt convertite fie în valori numerice, fie în șiruri, după caz. Adevărat va fi convertit la numărul 1 sau șirul „1”, iar falsul va fi convertit la 0 sau „0”. În schimb, numărul 1 va fi convertit în adevărat, iar numărul 0 va fi convertit în fals. De asemenea, falsul va fi convertit

valorile sunt nule și nedefinite.

Partea a III-a. Comportamentul paginilor web. Scripturi web

Se poate vedea că JavaScript se luptă să execute corect chiar și expresiile scrise incorect. Uneori funcționează, dar mai des totul nu funcționează conform planificării și, în cele din urmă, executarea scriptului Web este întreruptă datorită descoperirii unei erori într-un loc complet diferit, pe operatorul absolut corect. Prin urmare, este mai bine să nu permiteți astfel de incidente.

Prioritatea operatorului

Ultima problemă pe care o vom analiza aici este prioritatea operatorului. După cum ne amintim, prioritatea afectează ordinea în care instrucțiunile sunt executate într-o expresie.

Să existe următoarea expresie:

În acest caz, mai întâi valoarea lui c se va adăuga la valoarea variabilei b și apoi se va scădea din sumă 10. Operatorii acestei expresii au aceeași prioritate și, prin urmare, sunt executați strict de la stânga la dreapta.

Acum, ia în considerare o expresie ca aceasta:

Aici, mai întâi, valoarea lui c va fi înmulțită cu 10 și abia apoi va fi adăugată valoarea b la produsul rezultat. Operatorul de multiplicare are prioritate față de operatorul de adunare, astfel încât va fi încălcată o ordonare strictă de la stânga la dreapta.

Operatorii de sarcini au cea mai mică prioritate. Acesta este motivul pentru care expresia în sine este evaluată mai întâi, iar apoi rezultatul acesteia este atribuit unei variabile.

V În general, principiul de bază al execuției tuturor operatorilor este după cum urmează: operatorii cu o prioritate mai mare sunt executați mai întâi și numai apoi operatorii cu o prioritate mai mică. Operatorii cu aceeași prioritate sunt executați în ordinea în care apar (de la stânga la dreapta).

V filă. 14.9 enumeră toți operatorii pe care i-am studiat în ordinea descrescătoare a priorității lor.

Tabelul 14.9. Prioritatea operatorului (ordinea descrescătoare)

Operatori

Descriere

++ - - ~! tip de

Increment, decrement, schimbare semn, NU logic, inferență de tip

Înmulțirea, divizarea, luând restul

Adunarea și concatenarea șirurilor, scăderea

Operatori de comparație

Logic ȘI

Capitolul 14. Introducere în programarea web. Limbaj JavaScript

Tabelul 14.9 (sfârșit)

Operatori

Descriere

OR logic

Operator condiționat (vezi mai jos)

= <оператор>=

Atribuire, simplă și complexă

ATENŢIE!

Amintiți-vă acest tabel. Ordinea incorectă de executare a instrucțiunilor poate duce la erori greu de detectat, în care o expresie aparent absolut corectă dă un rezultat incorect.

Dar dacă trebuie să încălcăm ordinea normală de execuție a declarațiilor? Să folosim paranteze. Cu această notație, declarațiile cuprinse între paranteze sunt executate mai întâi:

a = (b + c) * 10;

Aici, adăugarea valorilor variabilelor b și c va fi efectuată mai întâi, iar apoi suma rezultată va fi înmulțită cu 10.

Operatorii închiși între paranteze sunt, de asemenea, supuși priorității. Prin urmare, sunt utilizate adesea mai multe paranteze imbricate:

a = ((b + c) * 10 - d) / 2 + 9;

Aici instrucțiunile vor fi executate în următoarea succesiune:

1. Adunarea b și c.

2. Înmulțiți suma rezultată cu 10.

3. Scăderea d din produs.

4. Împărțind diferența la 2.

5. Adăugați 9 la coeficient.

Dacă eliminați parantezele:

a = b + c * 10 - d / 2 + 9;

atunci ordinea de execuție a operatorilor va fi după cum urmează:

1. Înmulțirea lui c și 10.

2. Împărțind d la 2.

3. Adăugarea b și produsele c și 10.

4. Scăderea coeficientului din divizare din suma rezultată d de 2.

5. Adăugând 9 la diferența rezultată.

Rezultatul este complet diferit, nu-i așa?

  • Nedefinit nedefinit"
  • Nul: „obiect”
  • Boolean: „boolean”
  • Număr: „număr”
  • Șir: „șir”
  • Funcție: "funcție"
  • Orice altceva: „obiect”

Următoarele note ar trebui adăugate la acest tabel:

1. typeof nul === "obiect".

Teoretic, acesta este un punct subtil. În limbile tipizate static, o variabilă de tip obiect nu poate conține un obiect (NULL, zero, pointer nul).

În practică, acest lucru este incomod în JavaScript. Deci, dezvoltatorii ES 5.1 vor face un lucru mai intuitiv: typeof null === "null".

Dar, de vreme ce avem ES3 până acum, nu faceți nicio greșeală, de exemplu, în acest sens:

/ * Funcția caută un obiect și îl returnează sau nul dacă nu se găsește nimic * / funcția căutare () () var obj = căutare (); if (typeof obj === "obiect") (// am găsit de fapt obiectul (FAIL) obj.method ();)

2. Nu uitați de obiectele învelitoare (tipul numărului nou (5) === „obiect”).

3. Și nu uitați de dreptul browserelor de a face orice cu obiecte-gazdă.

Nu vă mirați că Safari crede cu încăpățânare că HTMLCollection este un tip de funcție, iar IE înainte de versiunea 9 a păstrat funcția noastră alertă () preferată ca obiect. De asemenea, Chrome obișnuia să considere RegExp ca funcție, dar acum pare să fi simțit și răspunde la acesta cu obiect.

toString ()

Încercarea de a afla tipul unei valori din rezultatul metodei sale toString () este inutilă. În toate „clasele” această metodă este redefinită la propria ei.

Metoda este bună pentru afișarea informațiilor de depanare, dar tipul unei variabile nu poate fi determinat de aceasta.

Object.prototype.toString ()

Deși toString este redefinit în cadrul „claselor” concrete, avem încă implementarea inițială din Object. Să încercăm să-l folosim:

console.log (Object .prototype .toString .call (value));

console.log (Object.prototype.toString.call (valoare));


Clinton diluează această povară

În mod ironic, această metodă funcționează surprinzător de bine.

Pentru tipurile scalare, returnează ,,,.

Lucrul amuzant este că se întoarce chiar și noul număr (5) pentru care tip de eșuare.

Metoda eșuează pe nul și nedefinit. Se revin diferite browsere, uneori așteptate și alteori în general. Cu toate acestea, este ușor să se determine tipul acestor două valori fără ea.

Distracția începe când ajungem la obiecte (cele cu typeof === „obiect”).

obiectele încorporate funcționează, practic, cu un bang:

  • {} —
  • Data -
  • Eroare -
  • RegExp -

Singurul lucru care iese din lista argumentelor este că, atunci.
Cu obiectele gazdă, lucrurile se înrăutățesc din nou.

În IE, obiectele DOM au început să devină obiecte „normale” doar din versiunea a 8-a și apoi nu chiar până la capăt. Prin urmare, în IE 6-8, toate aceste obiecte (HTMLCOllection, DOMElement, TextNode și împreună cu documentul și fereastra) sunt convertite în simplu.

În toate celelalte browsere (inclusiv IE9), puteți face deja ceva cu rezultatul toString. Deși, de asemenea, totul nu este ușor: HTMLCollection este acolo, atunci. fereastră - apoi, apoi, apoi. Dar puteți încerca deja să obțineți ceva din asta.

Este mai dificil cu DOMElement: este afișat ca - propriul format pentru fiecare etichetă. Dar aici, sezonul regulat ne va ajuta.

Povestea este cam la fel cu alte obiecte gazdă (în locația și testele navigatorului). Oriunde, cu excepția IE, acestea pot fi identificate prin șir.

Dintre dezavantajele utilizării Object.prototype.toString ():

1. Această oportunitate nu este sfințită de standard. Și aici ar trebui mai degrabă să ne bucurăm că totul funcționează atât de bine și să nu ne plângem de unele defecte.

2. Determinarea tipului prin analiza șirului returnat printr-o metodă care nu este deloc pentru determinarea tipului și este apelată și la un obiect căruia nu îi aparține, lasă unele reziduuri pe suflet.

3. În vechiul IE, după cum puteți vedea, obiectele gazdă nu sunt în mod normal identificate.

Cu toate acestea, este o piesă destul de utilă atunci când este utilizată împreună cu alte instrumente.


Constructori

Și în cele din urmă, constructorii. Cine mai bine să spună despre „clasa” unui obiect din JS dacă nu constructorul său?

Nul și nedefinit nu au nici obiecte wrapper, nici constructori.

Restul tipurilor scalare au ambalaje, respectiv, puteți obține un constructor:

(5) .constructor === Număr; (Number .NaN) .constructor === Number; (adevărat) .constructor === Boolean; ("șir") .constructor === Șir;

(5) .constructor === Număr; (Number.NaN) .constructor === Number; (adevărat) .constructor === Boolean; ("șir"). constructor === Șir;

Dar instanceof nu va funcționa aici:

5 exemplu de număr; // Număr fals .NaN instanță a numărului; // falsă instanță adevărată a lui Boolean; // instanță falsă „șir” a șirului; // fals

5 exemplu de număr; // false Number.NaN instanceof Number; // falsă instanță adevărată a lui Boolean; // instanță falsă „șir” a șirului; // fals

(instanța va funcționa pentru noul îndelung răbdător Număr (5))

Cu funcții (care sunt și obiecte), instanceof va trece:

console.log ((function () ()) instanceof Function); // true console.log ((function () ()) .constructor === Function); // Adevărat

console.log ((function () ()) instanceof Function); // true console.log ((function () ()). constructor === Function); // Adevărat

Toate obiectele claselor încorporate sunt, de asemenea, ușor identificate de constructorii lor: Array, Date, RegExp, Error.

O problemă apare aici cu argumente, al căror constructor este Object.

Și al doilea cu obiectul în sine, sau mai bine zis, cum să-i referi un obiect creat printr-un constructor personalizat.

Numai obiectul de bază poate fi definit astfel:

obiect instanceof Object;

Ca una dintre variantele definiției - pentru a itera peste toate celelalte tipuri posibile (Array, Error ...) și dacă niciuna dintre ele nu se potrivește - "obiect".

Constructori și obiecte gazdă

Cu obiectele gazdă, lucrurile se înrăutățesc.

Să începem cu faptul că IE până la a 7-a versiune inclusiv nu le consideră deloc obiecte normale. Pur și simplu nu au constructori și prototipuri acolo (în orice caz, programatorul nu le poate atinge).

Alte browsere se descurcă mai bine. Există constructori și îi puteți folosi pentru a determina clasa de valoare. Numai că acestea sunt apelate diferit în diferite browsere. De exemplu, pentru HTMLCollection, constructorul va fi HTMLCollection sau NodeList sau chiar NodeListConstructor.

De asemenea, ar trebui să definiți un constructor de bază pentru DOMElement. În FF, acesta este, de exemplu, HTMLElement, de la care HTMLDivElement și altele sunt deja moștenite.

FireFox sub versiunea 10 și Opera sub versiunea 11 aruncă o farsă. Acolo constructorul colecției este Object.

constructor.name

Constructorii au, de asemenea, o proprietate de nume care poate fi utilă.

Acesta conține numele funcției constructor, de exemplu (5) .constructor.name === "Număr".

Dar:
1. În IE nu este deloc, chiar și în cel de-al 9-lea.
2. Browserele sculptează din nou totul în obiecte gazdă (și adesea nu au deloc această proprietate). În Opera, DOMElement are un nume de constructor în general Function.prototype.
3. argumentele este din nou „obiect”.

concluzii

Niciuna dintre metodele prezentate nu oferă o definiție sută la sută a tipului / clasei valorii în toate browserele. Cu toate acestea, împreună vă permit să faceți acest lucru.

În viitorul apropiat voi încerca să colectez toate datele din tabele și să dau un exemplu de funcție definitorie.

JavaScript sau Js(prescurtat) nu este un limbaj ușor, iar dezvoltatorii începători nu învață imediat despre el. La început învață elementele de bază și totul pare colorat și frumos. Mergând un pic mai adânc, apar matrici JavaScript, obiecte, apeluri de apel și altele asemenea, pe care creierul le elimină adesea.

În JavaScript, este important să verificați corect tipul unei variabile. Să presupunem că doriți să știți dacă o variabilă este o matrice sau un obiect? Cum se verifică corect? În acest caz special, există trucuri în timpul verificării și despre asta va fi vorba despre această intrare. Să începem imediat.

Verificarea tipului unei variabile

De exemplu, trebuie să verificați dacă o variabilă este un obiect, o matrice, un șir sau un număr. Puteți utiliza tipul pentru aceasta, dar nu va da întotdeauna adevărul, iar în exemplul de mai jos voi arăta de ce.

Am scris acest exemplu pentru a ilustra de ce tipul nu este întotdeauna alegerea corectă.

Var _comparison = (string: "string", int: 99, float: 13.555, object: (hello: "hello"), array: new Array (1, 2, 3)); // Returnează un tablou cu chei obiect var _objKeys = Object.keys (_comparison); pentru (var i = 0; i<= _objKeys.length - 1; i++) { // выведем в консоль тип каждой переменной console.log(typeof _comparson[_objKeys[i]]); }

Rezultatul executării codului:

Număr șir obiect obiect obiect

Dreapta? - Desigur că nu. Există două probleme. Fiecare dintre ele va fi descris în detaliu și va fi propusă o soluție.

Prima problemă: numărul flotant, ieșire ca număr

Comparison.float nu este un număr și ar trebui să fie un float în loc de număr. Pentru a remedia acest lucru, puteți crea o funcție cu validare ca în codul de mai jos.

Var _floatNumber = 9.22; var _notFloatNumber = 9; console.log (isFloat (_floatNumber)); console.log (isFloat (_notFloatNumber)); console.log (isFloat ("")); funcția isFloat (n) (return Number (n) === n && n% 1! == 0;)

Funcția isFloat () verifică toate valorile pentru numerele cu virgulă mobilă. În primul rând, verifică dacă variabila este egală cu n number (Number (n) === n) și dacă da, se face o altă verificare pentru împărțirea cu rest, iar dacă există un rest, atunci un boolean ( Adevărat sau fals) rezultat (n% 1! == 0).

În exemplul de mai sus, revine Adevărat, falsși fals... Primul sens este pluti tip, al doilea nu este - acesta este un număr obișnuit, iar ultimul este doar un șir gol care nu se potrivește regulilor.

A doua problemă: matricea a fost definită ca obiect

În primul exemplu, matricea a fost afișată ca obiect și acest lucru nu este foarte bun, deoarece uneori trebuie să utilizați acest tip special și nimic altceva.

Există mai multe moduri de a testa o variabilă pentru un tip de matrice.

Prima opțiune (opțiune bună). Verificăm dacă datele aparțin unei matrice folosind instanceof ().

Var date = Array nou („salut”, „lume”); var isArr = instanță de date a matricei;

A doua opțiune (opțiune bună). Metoda Array.isArray () returnează o valoare booleană, care va depinde dacă variabila este o matrice sau nu ().

Var date = Array nou („salut”, „lume”); var isArr = Array.isArray (date);

A treia opțiune (cea mai bună, dar cea mai lungă). Pentru comoditate, puteți face din aceasta o funcție. Folosind Object, o facem. Dacă rezultatul Object.prototype.toString.call (data) nu este egal atunci variabila nu este o matrice ().

Var date = Array nou („salut”, „lume”); var isArr = Object.prototype.toString.call (data) == ""; console.log (isArr);

Ultimul rezultat ca funcție de comoditate:

Funcția isArray (date) (returnează Object.prototype.toString.call (data) == "")

Acum puteți apela funcția isArray () și setați o matrice sau altceva ca argument și puteți vedea rezultatul.

Postfaţă

Înregistrarea sa dovedit a fi destul de mare decât a fost intenționată inițial. Dar sunt mulțumit de asta, deoarece descrie pe scurt și clar dificultățile în verificarea variabilelor în JavaScript și cum să le ocolească.

Dacă mai aveți întrebări - scrieți-le mai jos la această intrare. Voi fi bucuros să vă ajut.

Operator tip de returnează un șir care indică tipul operandului.

Sintaxă

Operandul urmează tipul de operator:

Tip de operand

Opțiuni

operand este o expresie care reprezintă un obiect sau primitiv al cărui tip urmează să fie returnat.

Descriere

Următorul tabel listează valorile posibile de returnare de tipof. Mai multe informații despre tipuri și primitive sunt pe pagina.

Exemple de

// Numere de tip 37 === "număr"; typeof 3.14 === "număr"; typeof (42) === "număr"; typeof Math.LN2 === "număr"; typeof Infinity === "număr"; typeof NaN === "număr"; // chiar dacă este tipul „Not-A-Number” Număr (1) === „număr”; // nu folosiți niciodată această intrare! // Șiruri de tip "" === "șir"; typeof "bla" === "șir"; tipul „1” === „șir”; // rețineți că numărul din interiorul șirului este încă de tip șir tipof (tipof 1) === "șir"; // typeof va returna întotdeauna un șir în acest caz typeof Șir ("abc") === "șir"; // nu folosiți niciodată această intrare! // Booleans typeof true === "boolean"; typeof false === "boolean"; typeof boolean (adevărat) === "boolean"; // nu folosiți niciodată această intrare! // Simboluri tip de simbol () === "simbol" tip de simbol ("foo") === "simbol" tip de simbol.iterator === "simbol" // Tip nedefinit de nedefinit === "nedefinit"; typeof declaratVariabilButUndefinat === "nedefinit"; typeof undeclaredVariable === "nedefinit"; // Obiecte tipof (a: 1) === "obiect"; // utilizați Array.isArray sau Object.prototype.toString.call // pentru a face distincția între obiecte obișnuite și tablouri typeof === "obiect"; typeof new Date () === "obiect"; // Ceea ce este mai jos duce la erori și probleme. Nu folosi! tip de nou Boolean (adevărat) === "obiect"; typeof new Number (1) === "obiect"; typeof new String ("abc") === "obiect"; // Funcții tipofuncție () () === "funcție"; tipul clasei C () === "funcție"; typeof Math.sin === "funcție";

nul

// Acest lucru a fost definit de la naștere JavaScript tip de nul === "obiect";

În prima implementare JavaScript, valorile au fost reprezentate printr-un tip de etichetă și o pereche de valori. Tipul de etichetă pentru obiecte a fost 0. null a fost reprezentat ca un indicator nul (0x00 pe majoritatea platformelor). Prin urmare, tipul de etichetă pentru nul a fost zero, deci valoarea de returnare a tipului este falsă. ()

O corecție a fost sugerată în ECMAScript (prin dezactivare), dar a fost respinsă. Acest lucru ar avea ca rezultat typeof null === "null".

Folosind noul operator

// Toate funcțiile constructorului create cu „new” vor fi de tip „object” var str = new String („String”); var num = număr nou (100); tip de str; // Returnează tipul „obiect” de num; // Returnează „obiect” // Dar există o excepție pentru constructorul de funcții var func = new Function (); tip de funcții; // Returnează „funcția”

Expresii obisnuite

Expresiile regulate apelabile au fost un supliment non-standard în unele browsere.

Typeof / s / === "funcție"; // Chrome 1-12 Nu este compatibil cu ECMAScript 5.1 tip de / s / === „obiect”; // Conform cu Firefox 5+ ECMAScript 5.1

Erori legate de zonele moarte temporare

Înainte de ECMAScript 2015, tipul operatorului avea garanția de a returna un șir pentru orice operand cu care a fost apelat. Acest lucru s-a schimbat odată cu adăugarea declarațiilor let și const non-hoisting cu scop de bloc. Acum, dacă variabilele sunt declarate cu let și const, iar typeof este apelat pentru ele în blocul de declarație variabilă, dar înainte de declarație, atunci se aruncă o ReferenceError. Comportamentul diferă de variabilele nedeclarate, pentru care tipul va returna "nedefinit". Variabilele cu scop de bloc se află într-o „zonă moartă temporară” care durează de la începutul blocului până când variabila este declarată. În această zonă, o încercare de a accesa variabile aruncă o excepție.

Typeof undeclaredVariable === "nedefinit"; typeof newLetVariable; let newLetVariable; // ReferenceError typeof newConstVariable; const newConstVariable = "salut"; // ReferenceError

Excepții

Toate browserele actuale au un document nestandard.toate obiectul gazdă de tip Nedefinit.

Typeof document.all === "nedefinit";

Deși specificația permite nume de tip personalizate pentru obiecte exotice nestandardizate, este necesar ca aceste nume să difere de cele predefinite. O situație în care document.all este nedefinit ar trebui considerată o încălcare excepțională a regulilor.

Specificații (editați)

Specificație stare Comentarii (1)
ECMAScript Ultimul proiect (ECMA-262)
Proiect
ECMAScript 2015 (ediția a 6-a, ECMA-262)
Definiția „tipului de operator” din această specificație.
Standard
ECMAScript 5.1 (ECMA-262)
Definiția „tipului de operator” din această specificație.
Standard
ECMAScript Ediția a 3-a (ECMA-262)
Definiția „tipului de operator” din această specificație.
Standard
ECMAScript prima ediție (ECMA-262)
Definiția „tipului de operator” din această specificație.
Standard Definiție originală. Implementat în JavaScript 1.1

Compatibilitatea browserului

Actualizați datele de compatibilitate pe GitHub

CalculatoareMobilServer
CromMargineFirefoxInternet ExplorerOperăSafariVizualizare web AndroidChrome pentru AndroidFirefox pentru AndroidOpera pentru AndroidSafari pe iOSSamsung InternetNode.js
tip deCrom Suport complet 1 Margine Suport complet 12 Firefox Suport complet 1 IE Suport complet 3 Operă Suport complet daSafari Suport complet daWebView Android Suport complet 1 Chrome Android Suport complet 18 Firefox Android Suport complet 4 Opera Android Suport complet daSafari iOS Suport complet daSamsung Internet Android Suport complet 1.0 nodejs Suport complet da

Legendă

Suport complet Suport complet

Note specifice IE

În IE 6, 7 și 8, multe obiecte gazdă sunt obiecte, dar nu funcții. De exemplu.