Qual è la differenza tra typeof e instanceof e quando si dovrebbe usare uno rispetto all'altro?


394

Nel mio caso particolare:

callback instanceof Function

o

typeof callback == "function"

importa, qual è la differenza?

Risorsa aggiuntiva:

Tipo JavaScript- Gardenof vs instanceof


2
Ho trovato la mia risposta qui come una soluzione facile da usare
CrandellWS,

1
C'è un altro modo per controllare il tipo usando Object.prototype.toString ecma-international.org/ecma-262/6.0/…
rab

1
usa .constructorinvece la proprietà.
Muhammad Umer,

Se ti chiedi delle prestazioni , vedi la mia risposta di seguito . typeof è più veloce dove entrambi sono applicabili (vale a dire oggetti).
Martin Peter,

Risposte:


540

Utilizzare instanceofper tipi personalizzati:

var ClassFirst = function () {};
var ClassSecond = function () {};
var instance = new ClassFirst();
typeof instance; // object
typeof instance == 'ClassFirst'; // false
instance instanceof Object; // true
instance instanceof ClassFirst; // true
instance instanceof ClassSecond; // false 

Utilizzare typeofper tipi incorporati semplici:

'example string' instanceof String; // false
typeof 'example string' == 'string'; // true

'example string' instanceof Object; // false
typeof 'example string' == 'object'; // false

true instanceof Boolean; // false
typeof true == 'boolean'; // true

99.99 instanceof Number; // false
typeof 99.99 == 'number'; // true

function() {} instanceof Function; // true
typeof function() {} == 'function'; // true

Utilizzare instanceofper tipi integrati complessi:

/regularexpression/ instanceof RegExp; // true
typeof /regularexpression/; // object

[] instanceof Array; // true
typeof []; //object

{} instanceof Object; // true
typeof {}; // object

E l'ultimo è un po 'complicato:

typeof null; // object

11
Questa risposta chiarisce perché instaceof non dovrebbe essere usato per tipi primitivi. È abbastanza ovvio che non hai un'opzione quando si tratta di tipi personalizzati, così come il vantaggio per i tipi di "oggetti". Ma cosa rende le funzioni unite a "tipi predefiniti semplici"? Trovo strano come una funzione si comporti come un oggetto, ma il suo tipo è "funzione" che rende possibile l'uso di "tipo di". Perché scoraggerei istanza di questo, però?
Assimilater,

4
@Assimilater potresti usare anche instanceof con le funzioni, tuttavia considero queste 3 regole molto semplici da ricordare e sì, le funzioni sono un'eccezione :)
Szymon Wygnański

2
un'altra parte difficile -> 'example string' instanceof String; // false ma new String ('example string') instanceof String; // vero
Luca,

2
@Luke generalmente una cattiva idea di usare "new String" in questo modo. che crea un "oggetto stringa" anziché una primitiva di stringa. vedere la sezione qui developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Colin D

4
Use instanceof for complex built in types- questo è ancora soggetto a errori. Meglio usare ES5 Array.isArray()et al. o gli spessori consigliati.
OrangeDog,

122

Entrambi sono simili nella funzionalità perché entrambi restituiscono informazioni sul tipo, tuttavia preferisco personalmente instanceofperché sta confrontando i tipi effettivi piuttosto che le stringhe. Il confronto dei tipi è meno soggetto all'errore umano ed è tecnicamente più veloce poiché confronta i puntatori in memoria anziché fare confronti di intere stringhe.


8
ci sono alcune situazioni in cui instanceof non funzionerà come previsto e typeof funziona bene ... developer.mozilla.org/En/Core_JavaScript_1.5_Reference/…
farinspace

55
instanceof funziona con oggetti nella stessa finestra. Se si utilizza iframe / frame o popup-windows ogni (i) frame / window ha il proprio oggetto "funzione" e l'istanza non riuscirà se si tenta di confrontare un oggetto con un altro (i) frame / window. typeof funzionerà in tutti i casi poiché restituisce la stringa "funzione".
circa

14
jsperf.com/typeof-function-vs-instanceof/3 Ho provato su Chrome e FF3.X, l'approccio "typeof" è più veloce.
Morgan Cheng,

10
Questo è solo falso. Non sono identici. Entrambi non funzionano in tutte le stesse situazioni, in particolare su VM e browser JavaScript diversi.
Forza Justin,

8
La tua risposta dice "entrambi sono essenzialmente identici in termini di funzionalità". Rispettosamente, questo è palesemente falso. Come delineato e spiegato nella mia risposta, nessuna delle due opzioni funziona in ogni situazione, in particolare tra i browser. L'approccio migliore consiste nell'utilizzare entrambi con un || operatore.
Forza Justin,

103

Un buon motivo per usare typeof è se la variabile potrebbe non essere definita.

alert(typeof undefinedVariable); // alerts the string "undefined"
alert(undefinedVariable instanceof Object); // throws an exception

Un buon motivo per usare instanceof è se la variabile può essere nulla.

var myNullVar = null;
alert(typeof myNullVar ); // alerts the string "object"
alert(myNullVar  instanceof Object); // alerts "false"

Quindi davvero secondo me dipenderà dal tipo di possibili dati che stai verificando.


11
+1 nota anche che instanceofnon può essere paragonato ai tipi primitivi, typeof can.
Tino,

3
In Chrome 29.0.1541.0 dev undefined instanceof Objectrestituisce false e non genera un'eccezione. Non so quanto sia recente quel cambiamento, ma rende instanceofpiù attraente.
Cypress Frankenfeld,

7
undefined instanceof Objectnon genera un'eccezione perché, eh, undefinedè definito. La costante esiste nello spazio dei nomi. Quando una variabile non esiste (a causa di errori di battitura per esempio), instanceof genererà un'eccezione. L'uso di typeof su una variabile inesistente produce invece "indefinito".
Cleong,

31

Per chiarire le cose, devi conoscere due fatti:

  1. L' operatore instanceof verifica se la proprietà prototipo di un costruttore appare in qualsiasi punto del file catena dei prototipi di un oggetto. Nella maggior parte dei casi ciò significa che l'oggetto è stato creato usando questo costruttore o sul suo discendente. Ma anche il prototipo può essere impostato esplicitamente dal Object.setPrototypeOf()metodo (ECMAScript 2015) o dalla __proto__proprietà (vecchi browser, obsoleto). Non è consigliabile modificare il prototipo di un oggetto, a causa di problemi di prestazioni.

Quindi instanceof è applicabile solo agli oggetti. Nella maggior parte dei casi non si utilizzano costruttori per creare stringhe o numeri. Puoi. Ma non lo fai quasi mai.

Inoltre, instanceof non può controllare, esattamente quale costruttore è stato usato per creare l'oggetto, ma restituirà true, anche se l'oggetto è derivato dalla classe che viene controllata. Nella maggior parte dei casi questo è il comportamento desiderato, ma a volte non lo è. Quindi devi tenerlo a mente.

Un altro problema è che ambiti diversi hanno ambienti di esecuzione diversi. Ciò significa che hanno diversi built-in (diversi oggetti globali, diversi costruttori, ecc.). Ciò può comportare risultati imprevisti.

Ad esempio, [] instanceof window.frames[0].Arraytornerà false, perché Array.prototype !== window.frames[0].Arraye le matrici ereditano dal primo.
Inoltre, non può essere utilizzato su un valore indefinito, perché non ha un prototipo.

  1. L' operatore typeof verifica se il valore appartiene a uno dei sei tipi di base : " number ", " string ", " boolean ", " object ", " function " o " non definito ". Dove la stringa "oggetto" appartiene a tutti gli oggetti (tranne le funzioni, che sono oggetti, ma hanno il loro valore nell'operatore typeof), e anche il valore "null" e le matrici (per "null" è un bug, ma questo bug è così vecchio , quindi è diventato uno standard). Non si basa su costruttori e può essere utilizzato anche se il valore non è definito. Ma non fornisce alcun dettaglio sugli oggetti. Quindi, se ne avevi bisogno, vai su instanceof.

Ora parliamo di una cosa difficile. Cosa succede se si utilizza il costruttore per creare un tipo primitivo?

let num = new Number(5);
console.log(num instanceof Number); // print true
console.log(typeof num); // print object
num++; //num is object right now but still can be handled as number
//and after that:
console.log(num instanceof Number); // print false
console.log(typeof num); // print number

Sembra magia. Ma non è. È il cosiddetto boxing (che racchiude il valore primitivo per oggetto) e unboxing (che estrae il valore primitivo spostato dall'oggetto). Tale tipo di codice sembra essere "un po '" fragile. Ovviamente puoi semplicemente evitare di creare un tipo primitivo con i costruttori. Ma c'è un'altra possibile situazione, quando la boxe può colpirti. Quando si utilizza Function.call () o Function.apply () su un tipo primitivo.

function test(){
  console.log(typeof this);
} 
test.apply(5);

Per evitare ciò, puoi usare la modalità rigorosa:

function test(){
  'use strict';
  console.log(typeof this);
} 
test.apply(5);

upd: A partire da ECMAScript 2015, esiste un altro tipo chiamato Symbol, che ha il proprio typeof == "symbol" .

console.log(typeof Symbol());
// expected output: "symbol"

Puoi leggerlo su MDN: ( Symbol , typeof ).


2
if an object is created by a given constructor Questo non è corretto o instanceof Crestituirà true se o eredita da C.prototype. Ne hai parlato più avanti nella tua risposta, ma non è molto chiaro.
oyenamit,

1
errato ... dal libro: " github.com/getify/You-Dont-Know-JS " un'istanza di Foo; // true L'operatore instanceof accetta un oggetto semplice come operando di sinistra e una funzione come operando di destra. La domanda dell'istanza di risposta è: nell'intera catena [[Prototype]] di a, l'oggetto mai arbitrariamente indicato da Foo.prototype appare mai?
Deen John,

1
Ho modificato la risposta, per essere più corretti. Grazie per i tuoi commenti
Vladimir Liubimov,

Inoltre, è stata aggiunta la spiegazione del problema di boxe / unboxing.
Vladimir Liubimov,

15

Ho scoperto un comportamento davvero interessante (letto come "orribile") in Safari 5 e Internet Explorer 9. Lo stavo usando con grande successo in Chrome e Firefox.

if (typeof this === 'string') {
    doStuffWith(this);
}

Quindi eseguo il test in IE9 e non funziona affatto. Grande sorpresa. Ma in Safari è intermittente! Quindi inizio il debug e trovo che Internet Explorer ritorni semprefalse . Ma la cosa più strana è che Safari sembra fare una sorta di ottimizzazione nella sua VM JavaScript, dove è truela prima volta, ma false ogni volta che colpisci ricaricare!

Il mio cervello è quasi esploso.

Quindi ora ho deciso su questo:

if (this instanceof String || typeof this === 'string')
    doStuffWith(this.toString());
}

E ora tutto funziona alla grande. Nota che puoi chiamare "a string".toString()e restituisce solo una copia della stringa, ad es

"a string".toString() === new String("a string").toString(); // true

Quindi userò entrambi d'ora in poi.


8

Altre differenze pratiche significative:

// Boolean

var str3 = true ;

alert(str3);

alert(str3 instanceof Boolean);  // false: expect true  

alert(typeof str3 == "boolean" ); // true

// Number

var str4 = 100 ;

alert(str4);

alert(str4 instanceof Number);  // false: expect true   

alert(typeof str4 == "number" ); // true

7

instanceoffunziona anche quando callbackè un sottotipo di Function, penso


4

instanceofin Javascript può essere traballante - credo che i principali framework provino a evitarne l'uso. Finestre diverse sono uno dei modi in cui possono rompersi: credo che anche le gerarchie di classi possano confonderlo.

Esistono modi migliori per verificare se un oggetto è un determinato tipo incorporato (che di solito è quello che desideri). Creare funzioni di utilità e usarle:

function isFunction(obj) {
  return typeof(obj) == "function";
}
function isArray(obj) {
  return typeof(obj) == "object" 
      && typeof(obj.length) == "number" 
      && isFunction(obj.push);
}

E così via.


2
Nel caso non lo sapessi: typeof non ha bisogno di parentesi poiché è una parola chiave e non una funzione. E IMHO dovresti usare === invece di ==.
circa

5
@some Hai ragione su typeof ma in questo caso non è necessario per ===, è necessario solo quando il valore confrontato potrebbe essere uguale senza avere lo stesso tipo. Qui non può.
Nicole

@some restituisce mai typeof qualcosa di diverso da una stringa?
Kenneth J,

Quindi isArray sarebbe sbagliato, per esempio, per un oggetto stack con un metodo push e un attributo di lunghezza numerica. In quali circostanze (esempio di array) sarebbe sbagliato?
Chris Noe,

@ChrisNoe Il problema sorge con oggetti condivisi tra più frame: groups.google.com/forum/#!msg/comp.lang.javascript/XTWYCOwC96I/…

3

instanceofnon funzionerà per i primitivi, ad esempio "foo" instanceof Stringtornerà falsementre typeof "foo" == "string"tornerà true.

D'altra parte typeof, probabilmente non farà ciò che vuoi quando si tratta di oggetti personalizzati (o classi, qualunque cosa tu voglia chiamarli). Per esempio:

function Dog() {}
var obj = new Dog;
typeof obj == 'Dog' // false, typeof obj is actually "object"
obj instanceof Dog  // true, what we want in this case

Accade semplicemente che le funzioni sono sia primitive di "funzione" sia istanze di "Funzione", il che è un po 'strano dato che non funziona così per altri tipi primitivi, ad es.

(typeof function(){} == 'function') == (function(){} instanceof Function)

ma

(typeof 'foo' == 'string') != ('foo' instanceof String)

3

Consiglierei di usare il prototipo callback.isFunction().

Hanno capito la differenza e puoi contare sulla loro ragione.

Immagino che anche altri framework JS abbiano queste cose.

instanceOfnon funzionerebbe su funzioni definite in altre finestre, credo. La loro funzione è diversa dalla tua window.Function.


3

Quando si controlla una funzione, si deve sempre usare typeof.

Ecco la differenza:

var f = Object.create(Function);

console.log(f instanceof Function); //=> true
console.log(typeof f === 'function'); //=> false

f(); // throws TypeError: f is not a function

Questo è il motivo per cui non si deve mai usare instanceofper verificare una funzione.


Posso affermare che typeofè sbagliato - fè tutto quanto segue: un Object(un oggetto) e un Function(una funzione). Tranne per me ha più senso usare instanceofperché sapendo che è una funzione, so che è anche un oggetto, poiché tutte le funzioni sono oggetti in ECMAScript. Il contrario non è vero - sapendo typeofche fè davvero un objectnon ho idea che sia anche una funzione.
AMN

@amn Per me, è un'istanza rotta della funzione. Diventa attributi come length, namee calldalla funzione, ma tutti sono defunta. Quel che è peggio, non può essere chiamato e la TypeErrordice: f is not a function.
Maaartinus,

2

Significativa differenza pratica:

var str = 'hello word';

str instanceof String   // false

typeof str === 'string' // true

Non chiedermi perché.


11
Perché qui strc'è una stringa primitiva, non un oggetto stringa. Lo stesso vale per primitive numeriche e primitive booleane, non sono istanze delle loro controparti "costruite", gli oggetti String, Number e Boolean. JavaScript converte automaticamente queste tre primitive in oggetti quando richiesto (ad esempio utilizzando un metodo sulla catena di prototipi dell'oggetto). Il rovescio della medaglia della tua differenza pratica, instanceof è meglio per verificare la presenza di array da allora typeof [] == "object" // true.
Andy E

2

Prestazione

typeofè più veloce che instanceofnelle situazioni in cui entrambi sono applicabili.

A seconda del motore, la differenza di prestazioni a favore di typeofpotrebbe essere di circa il 20% . ( Il tuo chilometraggio può variare )

Ecco un test di riferimento per Array:

var subject = new Array();
var iterations = 10000000;

var goBenchmark = function(callback, iterations) {
    var start = Date.now();
    for (i=0; i < iterations; i++) { var foo = callback(); }
    var end = Date.now();
    var seconds = parseFloat((end-start)/1000).toFixed(2);
    console.log(callback.name+" took: "+ seconds +" seconds.");
    return seconds;
}

// Testing instanceof
var iot = goBenchmark(function instanceofTest(){
     (subject instanceof Array);
}, iterations);

// Testing typeof
var tot = goBenchmark(function typeofTest(){
     (typeof subject == "object");
}, iterations);

var r = new Array(iot,tot).sort();
console.log("Performance ratio is: "+ parseFloat(r[1]/r[0]).toFixed(3));

Risultato

instanceofTest took: 9.98 seconds.
typeofTest took: 8.33 seconds.
Performance ratio is: 1.198

1
typeof subject == "array" dovrebbe restituire false. il tipo di soggetto è "oggetto".
Shardul,

come mai typeof è più veloce? Javascript sta internando le stringhe letterali?
Gregory Magarshak,

Il motivo è: segue instanceof sempre la catena di prototipi dell'oggetto, quindi la penalità delle prestazioni dipenderà da quanto la catena di prototipi è la classe, instanceofviene confrontata. Quindi per una catena ereditaria corta la penalità sarà più bassa (come [] instanceof Array,, {} instanceof Object) e per molto più grande. Quindi, se entrambi obj instanceof SomeClasse typeof obj !== 'string'significano lo stesso dal punto di vista di un tuo ipotetico codice (ad esempio se stai solo facendo un test ife non switchpassando attraverso più classi ecc.), Allora è meglio scegliere il secondo, dal punto di vista del rendimento,
ankhzet,

2

Questo è solo conoscenze complementari a tutte le altre spiegazioni qui - sto , non suggerendo di utilizzare .constructorovunque.

TL; DR: in situazioni in cui typeofnon è disponibile un'opzione e quando sai che non ti interessa la catena del prototipo , Object.prototype.constructorpuò essere un'alternativa praticabile o addirittura migliore di instanceof:

x instanceof Y
x.constructor === Y

È nello standard dall'1.1, quindi non preoccuparti della compatibilità con le versioni precedenti.

Muhammad Umer lo ha brevemente menzionato in un commento da qualche parte anche qui. Funziona su tutto con un prototipo, quindi non tutto nullo undefined:

// (null).constructor;      // TypeError: null has no properties
// (undefined).constructor; // TypeError: undefined has no properties

(1).constructor;                 // function Number
''.constructor;                  // function String
([]).constructor;                // function Array
(new Uint8Array(0)).constructor; // function Uint8Array
false.constructor;               // function Boolean()
true.constructor;                // function Boolean()

(Symbol('foo')).constructor;     // function Symbol()
// Symbols work, just remember that this is not an actual constructor:
// new Symbol('foo'); //TypeError: Symbol is not a constructor

Array.prototype === window.frames.Array;               // false
Array.constructor === window.frames.Array.constructor; // true

Inoltre, a seconda del caso d'uso, può essere molto più veloce di instanceof(il motivo è probabilmente che non deve controllare l'intera catena del prototipo). Nel mio caso avevo bisogno di un modo rapido per verificare se un valore è un array tipizzato:

function isTypedArrayConstructor(obj) {
  switch (obj && obj.constructor){
    case Uint8Array:
    case Float32Array:
    case Uint16Array:
    case Uint32Array:
    case Int32Array:
    case Float64Array:
    case Int8Array:
    case Uint8ClampedArray:
    case Int16Array:
      return true;
    default:
      return false;
  }
}

function isTypedArrayInstanceOf(obj) {
  return obj instanceof Uint8Array ||
    obj instanceof Float32Array ||
    obj instanceof Uint16Array ||
    obj instanceof Uint32Array ||
    obj instanceof Int32Array ||
    obj instanceof Float64Array ||
    obj instanceof Int8Array ||
    obj instanceof Uint8ClampedArray ||
    obj instanceof Int16Array;
}

https://run.perf.zone/view/isTypedArray-constructor-vs-instanceof-1519140393812

E i risultati:

Chrome 64.0.3282.167 (64 bit, Windows)

Istanza di array tipizzato vs costruttore - 1,5 volte più veloce in Chrome 64.0.3282.167 (64 bit, Windows)

Firefox 59.0b10 (64 bit, Windows)

Istanza di array tipizzato vs costruttore - 30 volte più veloce in Firefox 59.0b10 (64 bit, Windows)

Per curiosità, ho fatto un rapido benchmark del giocattolo contro typeof; sorprendentemente non funziona molto peggio, e sembra anche un po 'più veloce in Chrome:

let s = 0,
    n = 0;

function typeofSwitch(t) {
    switch (typeof t) {
        case "string":
            return ++s;
        case "number":
            return ++n;
        default:
            return 0;
    }
}

// note: no test for null or undefined here
function constructorSwitch(t) {
    switch (t.constructor) {
        case String:
            return ++s;
        case Number:
            return ++n;
        default:
            return 0;
    }
}

let vals = [];
for (let i = 0; i < 1000000; i++) {
    vals.push(Math.random() <= 0.5 ? 0 : 'A');
}

https://run.perf.zone/view/typeof-vs-constructor-string-or-number-1519142623570

NOTA: l'ordine in cui sono elencate le funzioni cambia tra le immagini!

Chrome 64.0.3282.167 (64 bit, Windows)

Tipo di stringa / numero di costruttore - 1,26 volte più veloce in Chrome 64.0.3282.167 (64 bit, Windows)

Firefox 59.0b10 (64 bit, Windows)

NOTA: l'ordine in cui sono elencate le funzioni cambia tra le immagini!

String / Number typeof vs constructor - 0.78x più lento in Firefox 59.0b10 (64-bit, Windows)


1

Usa instanceof perché se cambi il nome della classe otterrai un errore del compilatore.


1

var newObj =  new Object;//instance of Object
var newProp = "I'm xgqfrms!" //define property
var newFunc = function(name){//define function 
	var hello ="hello, "+ name +"!";
	return hello;
}
newObj.info = newProp;// add property
newObj.func = newFunc;// add function

console.log(newObj.info);// call function
// I'm xgqfrms!
console.log(newObj.func("ET"));// call function
// hello, ET!

console.log(newObj instanceof Object);
//true
console.log(typeof(newObj));
//"object"


Cosa devo fare, posso ottenere UA (navigator.userAgent)?
xgqfrms,

0

Provenendo da una rigida educazione OO, sceglierei

callback instanceof Function

Le stringhe sono inclini alla mia orribile ortografia o ad altri errori di battitura. Inoltre sento che legge meglio.


0

Nonostante instanceof possa essere un po 'più veloce di typeof , preferisco il secondo a causa di una tale magia possibile:

function Class() {};
Class.prototype = Function;

var funcWannaBe = new Class;

console.log(funcWannaBe instanceof Function); //true
console.log(typeof funcWannaBe === "function"); //false
funcWannaBe(); //Uncaught TypeError: funcWannaBe is not a function

0

Un altro caso è che puoi solo confrontarti con instanceof: restituisce vero o falso. Con typeofte puoi ottenere il tipo di qualcosa fornito


0

tenendo conto delle prestazioni, è meglio usare typeof con un tipico hardware, se si crea uno script con un ciclo di 10 milioni di iterazioni l'istruzione: typeof str == 'string' richiederà 9ms mentre 'string' instanceof String richiederà 19ms


0

Certo che importa ........!

Esaminiamo questo con esempi. Nel nostro esempio dichiareremo la funzione in due modi diversi.

Useremo sia function declaratione Constructor funzione . Vedremo come typeofe come instanceofsi comporteranno in questi due diversi scenari.

Creare una funzione usando la dichiarazione di funzione:

function MyFunc(){  }

typeof Myfunc == 'function' // true

MyFunc instanceof Function // false

Una possibile spiegazione per un risultato così diverso è, quando abbiamo fatto una dichiarazione di funzione, typeofpuò capire che si tratta di una funzione. typeofPerché controlla se l'espressione su quale tipo di operazione è operata, nel nostro caso ha implementato il Metodo di chiamata o meno . Se implementa il metodo è una funzione. Altrimenti no. Per chiarimenti controlla le specifiche ecmascript per typeof .MyFunc Call

Creare una funzione usando il costruttore di funzioni:

var MyFunc2 = new Function('a','b','return a+b') // A function constructor is used 

typeof MyFunc2 == 'function' // true

MyFunc2 instanceof Function // true

Qui typeofafferma che MyFunc2è una funzione oltre che l' instanceofoperatore. Sappiamo già typeofcontrollare se il metodo MyFunc2implementato Callo meno. Come MyFunc2è una funzione e implementa il callmetodo, ecco come typeofsa che è una funzione. D'altra parte, abbiamo usato function constructorper crearlo MyFunc2, diventa un'istanza di Function constructor. Ecco perché instanceofsi risolve anche true.

Cosa c'è di più sicuro da usare?

Come possiamo vedere in entrambi i casi, l' typeofoperatore può affermare con successo che abbiamo a che fare con una funzione qui, è più sicuro di instanceof. instanceoffallirà in caso di function declarationperché function declarationsnon sono un'istanza di Function constructor.

La migliore pratica :

Come suggerito da Gary Rafferty , il modo migliore dovrebbe essere usare sia typeof che instanceof insieme.

  function isFunction(functionItem) {

        return typeof(functionItem) == 'function' || functionItem instanceof Function;

  }

  isFunction(MyFunc) // invoke it by passing our test function as parameter

qualsiasi critica costruttiva riguardo a questa risposta sarà apprezzata.
AL-zami,

0

Per essere molto precisi, occorre usare l' istanza di dove il valore viene creato tramite il costruttore (generalmente tipi personalizzati) per es

var d = new String("abc")

mentre typeof per controllare i valori creati solo da assegnazioni per es

var d = "abc"

0

non c'è bisogno di sopraffare con tonnellate di esempi di cui sopra, basta tenere a mente due punti di vista:

  1. typeof var;è un operatore unario restituirà il tipo originale o il tipo root di var. in modo che restituisca tipi primitivi ( string, number, bigint, boolean, undefined, e symbol) o objecttipo.

  2. nel caso di oggetti di livello superiore, come oggetti incorporati (String, Number, Boolean, Array ..) o oggetti complessi o personalizzati, tutti sono di objecttipo root, ma il tipo di istanza costruito su di essi è variabile (come la classe OOP concetto di ereditarietà), qui a instanceof A- un operatore binario - ti aiuterà, passerà attraverso la catena di prototipi per verificare se appare il costruttore dell'operando giusto (A).

quindi ogni volta che vuoi controllare "root type" o lavorare con variabili primitive - usa "typeof", altrimenti usa "instanceof".

nullè un caso speciale, apparentemente primitivo, ma in effetti è un caso speciale per l'oggetto. Usare invece a === nullper controllare null.

d'altra parte, functionè anche un caso speciale, che è l'oggetto incorporato ma typeofrestituiscefunction

come puoi vedere, instanceofdevi passare attraverso la catena di prototipi nel frattempo typeofbasta controllare il tipo di root una volta, quindi è facile capire perché typeofè più veloce diinstanceof


0

Secondo la documentazione MDN su typeof , gli oggetti istanziati con la "nuova" parola chiave sono di tipo "oggetto":

typeof 'bla' === 'string';

// The following are confusing, dangerous, and wasteful. Avoid them.
typeof new Boolean(true) === 'object'; 
typeof new Number(1) === 'object'; 
typeof new String('abc') === 'object';

Mentre la documentazione su instanceof indica che:

const objectString = new String('String created with constructor');
objectString instanceOf String; // returns true
objectString instanceOf Object; // returns true

Quindi, se si desidera verificare, ad esempio, che qualcosa sia una stringa, non importa come sia stata creata, l'approccio più sicuro sarebbe usare instanceof.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.