Casa / Internet / Tipo di variabile di controllo Javascript. JavaScript, typeof, tipi e classi. Bug relativi a zone morte temporanee

Tipo di variabile di controllo Javascript. JavaScript, typeof, tipi e classi. Bug relativi a zone morte temporanee

Identificazione dinamica del tipo

Identificazione dinamica del tipo (RTTI) consente di determinare il tipo di un oggetto in fase di esecuzione. Risulta essere utile per una serie di motivi. In particolare, facendo riferimento alla classe base, è possibile determinare con precisione il tipo di oggetto accessibile da questo riferimento. L'identificazione dinamica del tipo consente inoltre di verificare in anticipo l'esito positivo del casting del tipo, prevenendo un'eccezione dovuta a un casting del tipo errato. Inoltre, l'identificazione dinamica del tipo è una componente importante della riflessione.

Per supportare l'identificazione dinamica del tipo, C# ne fornisce tre parole chiave a: is, as e typeof. Ognuna di queste parole chiave viene discussa ulteriormente a sua volta.

è operatore

Il tipo specifico di un oggetto può essere determinato utilizzando l'operatore is. Di seguito la sua forma generale:

l'espressione è tipo

dove espressione denota una singola espressione che descrive l'oggetto il cui tipo viene testato. Se l'espressione è di tipo compatibile o dello stesso tipo del tipo testato, il risultato di questa operazione è vero, altrimenti è falso. Pertanto, il risultato sarà vero se l'espressione è del tipo testato in una forma o nell'altra. Nell'operatore is, entrambi i tipi sono definiti come compatibili se sono dello stesso tipo o se viene fornita la conversione dei riferimenti, il boxing o l'unboxing.

Di seguito è riportato un esempio di utilizzo dell'operatore is:

Utilizzando il sistema; namespace ConsoleApplication1 ( class Add ( ) class Sum: Add ( ) class Program ( static void Main() ( Add a = new Add(); Sum s = new Sum(); if (a is Add) Console.WriteLine("Variabile a è di tipo Add"); if (s è Sum) Console.WriteLine("Il tipo di variabile s è ereditato dalla classe Add"); Console.ReadLine(); ) ) )

come operatore

A volte una conversione di tipo deve essere eseguita in fase di esecuzione, ma non generata se la conversione fallisce, il che è perfettamente possibile con un cast di tipo. L'operatore as serve a questo scopo e ha la seguente forma generale:

espressione come tipo

dove espressione denota una singola espressione convertibile nel tipo specificato.

Se il risultato di tale conversione ha esito positivo, viene restituito un riferimento al tipo, in caso contrario, un riferimento null. L'operatore as può essere utilizzato solo per conversione di riferimento, identità, boxing, unboxing. In alcuni casi, l'operatore as può essere una comoda alternativa all'operatore is. A titolo di esempio, si consideri il seguente programma:

Utilizzando il sistema; namespace ConsoleApplication1 ( class Add ( ) class Sum: Add ( ) class Program ( static void Main() ( Add a = new Add(); Sum s = new Sum(); // Esegue cast a = s come Add; if ( a != null) Console.WriteLine("Conversione riuscita"); else Console.WriteLine("Errore durante la conversione"); Console.ReadLine(); ) ) )

Il risultato dell'esecuzione di questo programma sarà una conversione riuscita.

a = (b > 0) && (c + 1 != d); indicatore = !(stato = 0);

Tabella 14.5. Operatori logici

Descrizione dell'operatore

! NOT (inversione logica)

&& AND (moltiplicazione booleana)

|| OR (addizione logica)

Tabella 14.6. Risultati dell'esecuzione degli operatori AND e OR

Operando 1

Operando 2

Tabella 14.7. Risultati dell'esecuzione dell'istruzione NOT

ottenere il tipo di operatore

Ottieni operatore di tipo typeof restituisce una stringa che descrive il tipo di dati dell'operando. L'operando di cui si vuole trovare il tipo è posto dopo questo operatore e racchiuso tra parentesi:

s = typeof("str");

Come risultato di questa espressione, la variabile s conterrà la stringa "string" , che denota il tipo di stringa.

Tutti i valori che possono essere restituiti tipo di operatore sono elencati in Tabella. 14.8.

Tabella 14.8. Valori restituiti dall'operatore typeof

Tipo di dati

Stringa di ritorno

Corda

Numerico

Tabella 14.8 (fine)

Tipo di dati

Stringa di ritorno

Logico

Compatibilità e conversione del tipo di dati

È giunto il momento di considerare due questioni più importanti: la compatibilità dei tipi di dati e la conversione da un tipo all'altro.

Cosa succede quando si sommano due numeri insieme? Esatto, un altro valore numerico. Cosa succede se aggiungi un numero e una stringa? È difficile da dire... Qui JavaScript incontra il problema dell'incompatibilità dei tipi di dati e cerca di rendere compatibili questi tipi convertendo uno di essi in un altro. Prima prova a convertire la stringa in un numero e, se ci riesce, esegue l'addizione. In caso di esito negativo, il numero verrà convertito in una stringa e le due stringhe risultanti verranno concatenate. Ad esempio, lo script Web nel Listato 14-6 convertirà il valore della variabile b quando aggiunto alla variabile a in un tipo numerico; quindi la variabile c conterrà il valore 23.

Listato 14.6

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

b = "12"; c = la + b;

d="Javascript"; e = 2;

Ma poiché il valore della variabile d non può essere convertito in un numero, il valore di e verrà convertito in una stringa e il risultato - il valore di f - diventerà uguale a

I valori booleani vengono convertiti in valori numerici o stringa, a seconda dei casi. True verrà convertito nel numero 1 o nella stringa "1" e false in 0 o "0" . Al contrario, il numero 1 verrà convertito in true e il numero 0 in false . Inoltre, false verrà convertito

siamo nulli e indefiniti.

Parte III. Comportamento della pagina web. Script web

Si può vedere che JavaScript fa fatica a eseguire correttamente anche le espressioni scritte in modo errato. A volte funziona, ma il più delle volte le cose non funzionano come previsto e alla fine lo script Web viene interrotto perché viene rilevato un errore in un punto completamente diverso dello script, nell'affermazione assolutamente corretta. Pertanto, è meglio evitare tali incidenti.

Precedenza dell'operatore

L'ultimo problema di cui ci occuperemo qui è la precedenza degli operatori. Come ricordiamo, la precedenza influisce sull'ordine in cui vengono eseguiti gli operatori in un'espressione.

Sia la seguente espressione:

In questo caso al valore della variabile b verrà prima aggiunto il valore di c, quindi alla somma verrà sottratto 10. Gli operatori di questa espressione hanno la stessa precedenza e quindi vengono eseguiti rigorosamente da sinistra verso destra.

Consideriamo ora questa espressione:

Qui, prima, il valore c verrà moltiplicato per 10 e solo allora il valore b verrà aggiunto al prodotto risultante. L'operatore di moltiplicazione ha una precedenza maggiore rispetto all'operatore di addizione, pertanto l'ordine "rigorosamente da sinistra a destra" verrà violato.

Gli operatori di assegnazione hanno la precedenza più bassa. Ecco perché l'espressione stessa viene valutata per prima, quindi il suo risultato viene assegnato a una variabile.

A In generale, il principio di base dell'esecuzione di tutti gli operatori è il seguente: prima vengono eseguiti gli operatori con una priorità più alta e solo allora gli operatori con una priorità inferiore. Gli operatori con la stessa precedenza vengono eseguiti nell'ordine in cui appaiono (da sinistra a destra).

A scheda. 14.9 elenca tutti gli operatori che abbiamo studiato in ordine decrescente di precedenza.

Tabella 14.9. Precedenza degli operatori (in ordine decrescente)

Operatori

Descrizione

++ -- - ~ ! tipo di

Incremento, decremento, cambio di segno, NOT logico, inferenza di tipo

Moltiplicazione, divisione, resto

Addizione e concatenazione di stringhe, sottrazione

Operatori di confronto

AND logico

Capitolo 14. Introduzione alla programmazione web. linguaggio javascript

Tabella 14.9 (fine)

Operatori

Descrizione

OR logico

Operatore condizionale (vedi sotto)

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

Compito, semplice e complesso

ATTENZIONE!

Ricorda questa tabella. L'errato ordine di esecuzione delle istruzioni può causare errori difficili da rilevare, in cui un'espressione apparentemente assolutamente corretta dà un risultato errato.

Ma cosa succede se abbiamo bisogno di rompere il normale ordine di esecuzione delle istruzioni? Usiamo le parentesi. In questa notazione, le istruzioni tra parentesi vengono eseguite per prime:

a = (b + c) * 10;

Qui verranno prima aggiunti i valori delle variabili b e c, quindi la somma risultante verrà moltiplicata per 10.

Anche gli operatori racchiusi tra parentesi sono soggetti a precedenza. Pertanto, vengono spesso utilizzate più parentesi nidificate:

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

Qui le istruzioni verranno eseguite nel seguente ordine:

1. Aggiungere b e c.

2. Moltiplica l'importo risultante per 10.

3. Sottrarre d dal prodotto.

4. Dividi la differenza per 2.

5. Addizione di 9 al quoziente.

Se rimuovi le parentesi:

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

quindi l'ordine di esecuzione degli operatori sarà il seguente:

1. Moltiplica c e 10.

2. Dividi d per 2.

3. Sommando b e moltiplicando c e 10.

4. Sottrazione dalla somma risultante del quoziente dalla divisione d a 2.

5. Aggiungendo 9 alla differenza risultante.

Si scopre un risultato completamente diverso, giusto?

javascript o JS(a breve) non è un linguaggio facile e gli sviluppatori alle prime armi non lo impareranno subito. All'inizio imparano le basi e tutto sembra colorato e bello. Andando un po' più a fondo, ci sono Array JavaScript, oggetti, richiami e tutto ciò che spesso lascia a bocca aperta.

In JavaScript, è importante controllare correttamente il tipo di una variabile. Diciamo che vuoi sapere se una variabile è un array o un oggetto? Come controllarlo correttamente? In questo caso particolare, ci sono trucchi durante la verifica ed è di questo che parlerà questo post. Iniziamo subito.

Verifica del tipo di una variabile

Ad esempio, è necessario verificare se una variabile è un oggetto, un array, una stringa o un numero. Puoi usare typeof per questo, ma non ti dirà sempre la verità, e ti mostrerò perché nell'esempio qui sotto.

Ho scritto questo esempio per illustrare perché typeof non è sempre la scelta giusta.

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

Risultato dell'esecuzione del codice:

String numero oggetto oggetto

Destra? - Ovviamente no. Ci sono due problemi. Ciascuno di essi sarà descritto in dettaglio e verrà proposta una soluzione.

Primo problema: numero float, output come numero

Comparison.float non è un numero e deve essere un float anziché un numero. Per risolvere questo problema, puoi creare una funzione con un segno di spunta come nel codice seguente.

Var_floatNumber = 9.22; var_notFloatNumber = 9; console.log(isFloat(_floatNumber)); console.log(isFloat(_notFloatNumber)); console.log(isFloat("")); funzione isFloat(n)( return Numero(n) === n && n % 1 !== 0; )

La funzione isFloat() controlla tutti i valori per i numeri in virgola mobile. Per prima cosa controlla se la variabile è uguale n number (Number(n) === n) e se sì, viene effettuato un altro controllo per la divisione con resto e se c'è un resto, viene restituito un valore booleano ( VERO o falso) risultato (n % 1 !== 0).

Nell'esempio sopra, restituisce VERO, falso e falso. Il primo significato è galleggiante digitare, il secondo no - questo è un numero normale e l'ultimo è solo una stringa vuota che non si adatta alle regole.

Secondo problema: l'array è stato definito come un oggetto

Nel primissimo esempio, l'array viene visualizzato come un oggetto, il che non è molto buono, perché a volte è necessario utilizzare questo tipo e nient'altro.

Esistono diversi modi per testare una variabile per un tipo di matrice.

La prima opzione (buona opzione). Controlla se i dati appartengono a un array usando instanceof().

Var data = new Array("ciao", "mondo"); var isArr = data instanceof Array;

La seconda opzione (buona opzione). Il metodo Array.isArray() restituisce un valore booleano che dipenderà dal fatto che la variabile sia o meno un array ().

Var data = new Array("ciao", "mondo"); var isArr = Array.isArray(dati);

La terza opzione (la migliore, ma lunga). Per comodità, puoi rendere questo metodo una funzione. Usando Object creiamo . Se il risultato di Object.prototype.toString.call(data) non è uguale, la variabile non è un array ().

Var data = new Array("ciao", "mondo"); var isArr = Object.prototype.toString.call(data) == ""; console.log(isArr);

L'ultimo risultato come funzione di convenienza:

Funzione isArray(data) ( return Object.prototype.toString.call(data) == "" )

Ora puoi chiamare le funzioni isArray() e impostare un array o qualcosa del genere come argomento e vedere il risultato.

Epilogo

Il record si è rivelato piuttosto grande di quanto originariamente previsto. Ma sono contento perché è abbastanza conciso e chiaro da descrivere le difficoltà di convalidare le variabili in JavaScript e come aggirarle.

In caso di domande, si prega di pubblicarle sotto questo post. Sarò felice di aiutarti.

Operatore tipo di restituisce una stringa che indica il tipo di operando.

Sintassi

L'operando segue l'operatore typeof:

tipo di operando

Opzioni

operandoè un'espressione che rappresenta l'oggetto o la primitiva il cui tipo deve essere restituito.

Descrizione

La tabella seguente elenca i possibili valori restituiti di typeof . Ulteriori informazioni su tipi e primitive sono disponibili nella pagina.

Esempi

// Numeri typeof 37 === "numero"; typeof 3.14 === "numero"; typeof(42) === "numero"; typeof Math.LN2 === "numero"; typeof Infinity === "numero"; typeof NaN === "numero"; // anche se è "Not-A-Number" typeof Number(1) === "number"; // non usare mai questa notazione! // Stringhe typeof "" === "stringa"; typeof "bla" === "stringa"; typeof "1" === "stringa"; // nota che il numero all'interno della stringa è ancora di tipo string typeof (typeof 1) === "string"; // typeof restituirà sempre una stringa in questo caso typeof String("abc") === "string"; // non usare mai questa notazione! // Booleans typeof true === "boolean"; typeof false === "booleano"; typeof Boolean(true) === "boolean"; // non usare mai questa notazione! // Symbols typeof Symbol() === "simbolo" typeof Symbol("foo") === "simbolo" typeof Symbol.iterator === "simbolo" // Undefined typeof undefined === "undefined"; typeof DeclarationButUndefinedVariable === "undefined"; typeof undeclaredVariable === "undefined"; // Oggetti typeof(a: 1) === "oggetto"; // usa Array.isArray o Object.prototype.toString.call // per distinguere tra oggetti regolari e array typeof === "object"; typeof new Date() === "oggetto"; // Qualunque cosa sotto porta a errori e problemi. Non usare! typeof new Boolean(true) === "oggetto"; typeof new Number(1) === "oggetto"; typeof new String("abc") === "oggetto"; // Funzioni typeof function() () === "funzione"; typeof class C() === "funzione"; typeof Math.sin === "funzione";

nullo

// Questo è stato definito sin dalla nascita di JavaScript typeof null === "object";

Nella prima implementazione di JavaScript, i valori erano rappresentati da un tipo di tag e una coppia di valori. Il tipo di tag per gli oggetti era 0. null era rappresentato come un puntatore null (0x00 sulla maggior parte delle piattaforme). Pertanto, il tipo del tag per null era null, quindi il valore restituito di typeof è fasullo. ()

È stata proposta una correzione in ECMAScript (tramite disabilita) ma è stata respinta. Ciò risulterebbe in typeof null === "null" .

Utilizzo dell'operatore new

// Tutte le funzioni di costruzione create con "new" saranno di tipo "object" var str = new String("String"); var num = nuovo Numero(100); typeofstr; // Restituisce "oggetto" typeof num; // Restituisce "oggetto" // Ma c'è un'eccezione per il costruttore di funzioni var func = new Function(); tipo di funzione; // Restituisce "funzione"

Espressioni regolari

Le espressioni regolari richiamate erano un'aggiunta non standard in alcuni browser.

Tipo di /s/ === "funzione"; // Chrome 1-12 Non compatibile con ECMAScript 5.1 typeof /s/ === "object"; // Firefox 5+ Conforme a ECMAScript 5.1

Bug relativi a zone morte temporanee

Prima di ECMAScript 2015, l'operatore typeof era garantito per restituire una stringa per qualsiasi operando con cui veniva chiamato. Ciò è cambiato con l'aggiunta di dichiarazioni let e const con ambito di blocco non di sollevamento. Ora, se le variabili vengono dichiarate con let e const e typeof viene richiamato su di esse nel blocco di dichiarazione delle variabili, ma prima della dichiarazione, viene generato un ReferenceError. Il comportamento è diverso dalle variabili non dichiarate, per le quali typeof restituirà "undefined". Le variabili con ambito di blocco si trovano in una "zona morta temporanea", che dura dall'inizio del blocco fino al momento in cui le variabili vengono dichiarate. In questa zona, un tentativo di accedere alle variabili genera un'eccezione.

Typeof undeclaredVariable === "undefined"; typeof newLetVariable; let newLetVariable; // ReferenceError typeof newConstVariable; const newConstVariable = "ciao"; // RiferimentoErrore

Eccezioni

In tutti i browser attuali esiste un oggetto host document.all non standard, che è di tipo Undefined.

Tipo di documento.all === "non definito";

Sebbene la specifica consenta nomi di tipi personalizzati per oggetti esotici non standard, questi nomi devono essere diversi da quelli predefiniti. La situazione in cui document.all è di tipo undefined dovrebbe essere considerata una violazione eccezionale delle regole.

Specifiche

Specifica Stato Commenti
ECMAScript ultima bozza (ECMA-262)
Brutta copia
ECMAScript 2015 (6a edizione, ECMA-262)
Definizione di "The typeof Operator" in questa specifica.
Standard
ECMAScript 5.1 (ECMA-262)
Definizione di "The typeof Operator" in questa specifica.
Standard
ECMAScript 3a edizione (ECMA-262)
Definizione di "The typeof Operator" in questa specifica.
Standard
ECMAScript 1a edizione (ECMA-262)
Definizione di "The typeof Operator" in questa specifica.
Standard Definizione iniziale. Implementato in JavaScript 1.1

Compatibilità browser

Aggiorna i dati di compatibilità su GitHub

ComputerMobileserver
CromobordoFirefoxInternet Explorermusica liricasafarivisualizzazione Web AndroidChrome per AndroidFirefox per AndroidOpera per AndroidSafari su iOSSamsung InternetNode.js
tipo diCromo Supporto totale 1 bordo Supporto totale 12 Firefox Supporto totale 1 CIOÈ Supporto totale 3 musica lirica Supporto totalesafari Supporto totalevisualizzazione web android Supporto totale 1 Chrome Android Supporto totale 18 FirefoxAndroid Supporto totale 4 OperaAndroid Supporto totaleSafari iOS Supporto totaleSamsung Internet Android Supporto totale 1.0 nodejs Supporto totale

Leggenda

Supporto totale Supporto totale

Note specifiche per IE

In IE 6, 7 e 8, molti oggetti host sono oggetti, non funzioni. Per esempio.