Dans mon cas particulier:
callback instanceof Function
ou
typeof callback == "function"
est-ce même important, quelle est la différence?
Ressource supplémentaire:
JavaScript-Garden typeof vs instanceof
javascript
instanceof
typeof
farinspace
la source
la source
Object.prototype.toString
ecma-international.org/ecma-262/6.0/….constructor
propriété à la place.Réponses:
Utilisez
instanceof
pour les types personnalisés:Utilisez
typeof
pour les types simples intégrés:Utilisation
instanceof
pour les types intégrés complexes:Et le dernier est un peu délicat:
la source
Use instanceof for complex built in types
- ceci est toujours sujet à erreur. Mieux vaut utiliser ES5Array.isArray()
et al. ou les cales recommandées.Les deux sont similaires dans la fonctionnalité car ils renvoient tous les deux des informations sur le type, mais je préfère personnellement
instanceof
car il compare les types réels plutôt que les chaînes. La comparaison de types est moins sujette aux erreurs humaines, et elle est techniquement plus rapide car elle compare les pointeurs en mémoire plutôt que de faire des comparaisons de chaînes entières.la source
Une bonne raison d'utiliser typeof est si la variable n'est pas définie.
Une bonne raison d'utiliser instanceof est si la variable peut être nulle.
Donc, vraiment, à mon avis, cela dépendrait du type de données possibles que vous vérifiez.
la source
instanceof
ne peut pas se comparer aux types primitifs, typeof peut.undefined instanceof Object
renvoie false et ne lève pas d'exception. Je ne sais pas à quel point ce changement est récent, mais il estinstanceof
plus attrayant.undefined instanceof Object
ne lève pas d'exception car, eh,undefined
est défini. La constante existe dans l'espace de noms. Lorsqu'une variable n'existe pas (à cause d'une faute de frappe par exemple), instanceof lèvera une exception. L'utilisation de typeof sur une variable inexistante donne par contre «indéfini».Pour clarifier les choses, vous devez connaître deux faits:
Object.setPrototypeOf()
méthode (ECMAScript 2015) ou par la__proto__
propriété (anciens navigateurs, obsolètes). Il n'est cependant pas recommandé de modifier le prototype d'un objet en raison de problèmes de performances.Ainsi instanceof ne s'applique qu'aux objets. Dans la plupart des cas, vous n'utilisez pas de constructeurs pour créer des chaînes ou des nombres. Vous pouvez. Mais vous ne le faites presque jamais.
De plus, instanceof ne peut pas vérifier exactement quel constructeur a été utilisé pour créer l'objet, mais renvoie true, même si l'objet est dérivé de la classe qui est vérifiée. Dans la plupart des cas, c'est le comportement souhaité, mais parfois ce n'est pas le cas. Vous devez donc garder cet esprit.
Un autre problème est que différentes étendues ont des environnements d'exécution différents. Cela signifie qu'ils ont des éléments intégrés différents (objet global différent, constructeurs différents, etc.). Cela peut entraîner des résultats inattendus.
Par exemple,
[] instanceof window.frames[0].Array
reviendrafalse
, carArray.prototype !== window.frames[0].Array
et les tableaux héritent de l'ancien.De plus, il ne peut pas être utilisé sur une valeur non définie, car il n'a pas de prototype.
Parlons maintenant d'une chose délicate. Et si vous utilisez un constructeur pour créer un type primitif?
On dirait de la magie. Mais ce n'est pas. C'est ce qu'on appelle la boxe (envelopper la valeur primitive par objet) et unboxing (extraire la valeur primitive enveloppée de l'objet). Ce type de code semble être "un peu" fragile. Bien sûr, vous pouvez simplement éviter de créer un type primitif avec des constructeurs. Mais il y a une autre situation possible, lorsque la boxe peut vous frapper. Lorsque vous utilisez Function.call () ou Function.apply () sur un type primitif.
Pour éviter cela, vous pouvez utiliser le mode strict:
upd: Depuis ECMAScript 2015, il existe un autre type appelé Symbol, qui a son propre typeof == "symbol" .
Vous pouvez en lire plus sur MDN: ( Symbol , typeof ).
la source
if an object is created by a given constructor
Ceci est une erreur.o instanceof C
retournera vrai si o hérite de C.prototype. Vous en avez parlé plus loin dans votre réponse, mais ce n'est pas très clair.J'ai découvert un comportement vraiment intéressant (lu comme "horrible") dans Safari 5 et Internet Explorer 9. J'utilisais cela avec beaucoup de succès dans Chrome et Firefox.
Ensuite, je teste dans IE9, et cela ne fonctionne pas du tout. Grosse surprise. Mais dans Safari, c'est intermittent! Je commence le débogage, et je trouve que Internet Explorer est toujours de retour
false
. Mais le plus étrange est que Safari semble faire une sorte d'optimisation dans sa machine virtuelle JavaScript où c'esttrue
la première fois, mais àfalse
chaque fois que vous appuyez sur recharger!Mon cerveau a presque explosé.
Alors maintenant, je me suis installé sur ceci:
Et maintenant, tout fonctionne très bien. Notez que vous pouvez appeler
"a string".toString()
et il retourne juste une copie de la chaîne, c'est-à-direJe vais donc utiliser les deux à partir de maintenant.
la source
Autres différences pratiques importantes:
la source
instanceof
fonctionne aussi quandcallback
est un sous-type deFunction
, je pensela source
instanceof
en Javascript peut être floconneux - je crois que les principaux frameworks essaient d'éviter son utilisation. Différentes fenêtres sont l'une des façons dont elles peuvent se briser - je crois que les hiérarchies de classes peuvent également les confondre.Il existe de meilleures façons de tester si un objet est d'un certain type intégré (ce qui est généralement ce que vous voulez). Créez des fonctions utilitaires et utilisez-les:
Etc.
la source
instanceof
ne fonctionnera pas pour les primitives, par exemple"foo" instanceof String
retournerafalse
alors quetypeof "foo" == "string"
reviendratrue
.D'un autre côté
typeof
, vous ne ferez probablement pas ce que vous voulez en ce qui concerne les objets personnalisés (ou les classes, peu importe comment vous les appelez). Par exemple:Il se trouve que les fonctions sont à la fois des primitives «fonction» et des instances de «Fonction», ce qui est un peu étrange étant donné que cela ne fonctionne pas comme ça pour d'autres types de primitives, par exemple.
mais
la source
Je recommanderais d'utiliser des prototypes
callback.isFunction()
.Ils ont compris la différence et vous pouvez compter sur leur raison.
Je suppose que d'autres frameworks JS ont aussi de telles choses.
instanceOf
ne fonctionnerait pas sur les fonctions définies dans d'autres fenêtres, je crois. Leur fonction est différente de la vôtrewindow.Function
.la source
Lors de la vérification d'une fonction, il faut toujours utiliser
typeof
.Voici la différence:
C'est pourquoi il ne faut jamais utiliser
instanceof
pour rechercher une fonction.la source
typeof
faux -f
c'est tout ce qui suit: unObject
(un objet) et unFunction
(une fonction). Sauf pour moi, cela a plus de sens à utiliserinstanceof
car sachant que c'est une fonction, je sais que c'est aussi un objet, car toutes les fonctions sont des objets dans ECMAScript. L'inverse n'est pas vrai - sachant detypeof
celaf
est en effet unobject
je n'ai aucune idée que c'est aussi une fonction.length
,name
etcall
de Function, mais tous sont obsolètes. Pire encore, il ne peut pas être appelé etTypeError
dit:f is not a function
.Différence pratique significative:
Ne me demandez pas pourquoi.
la source
str
une primitive chaîne, pas un objet chaîne. Il en va de même pour les primitives numériques et les primitives booléennes, ce ne sont pas des instances de leurs homologues "construits", les objets String, Number et Boolean. JavaScript convertit automatiquement ces trois primitives en objets lorsque cela est nécessaire (comme l'utilisation d'une méthode sur la chaîne de prototypes de l'objet). D'un autre côté de votre différence pratique, instanceof est mieux pour vérifier les tableaux depuistypeof [] == "object" // true
.Performance
typeof
est plus rapide queinstanceof
dans les situations où les deux sont applicables.Selon votre moteur, la différence de performances en faveur de
typeof
pourrait être de l'ordre de 20% . ( Votre kilométrage peut varier )Voici un test de référence pour
Array
:Résultat
la source
instanceof
toujours la chaîne de prototype de l'objet, donc la pénalité de performance dépendra de la distance dans laquelle la classe de prototype est la classe,instanceof
est testée. Ainsi, pour une chaîne d'héritage courte, la pénalité sera plus faible (comme[] instanceof Array
,,{} instanceof Object
), et pour longtemps - plus grande. Donc, si les deuxobj instanceof SomeClass
ettypeof obj !== 'string'
signifient la même chose du point de vue de votre code hypothétique (par exemple, si vous effectuez simplement un testif
et que vous ne passez passwitch
par plusieurs classes, etc.), vous feriez mieux d'en choisir un deuxième, en termes de performances,C'est juste une connaissance complémentaire à toutes les autres explications ici - je ne suggère pas d'utiliser
.constructor
partout.TL; DR: Dans les situations où ce
typeof
n'est pas une option, et quand vous savez que vous ne vous souciez pas de la chaîne prototype ,Object.prototype.constructor
peut être une alternative viable ou encore meilleure queinstanceof
:Il est dans la norme depuis la version 1.1, donc ne vous inquiétez pas de la compatibilité descendante.
Muhammad Umer l'a brièvement mentionné dans un commentaire quelque part ici aussi. Il fonctionne sur tout avec un prototype - donc tout n'est pas
null
ouundefined
:En outre, selon votre cas d'utilisation, cela peut être beaucoup plus rapide que
instanceof
(la raison étant probablement qu'il n'a pas à vérifier la chaîne de prototype entière). Dans mon cas, j'avais besoin d'un moyen rapide pour vérifier si une valeur est un tableau typé:https://run.perf.zone/view/isTypedArray-constructor-vs-instanceof-1519140393812
Et les résultats:
Chrome 64.0.3282.167 (64 bits, Windows)
Firefox 59.0b10 (64 bits, Windows)
Par curiosité, j'ai fait une comparaison rapide de jouets contre
typeof
; étonnamment, il ne fonctionne pas beaucoup moins bien, et il semble encore un peu plus rapide dans Chrome:https://run.perf.zone/view/typeof-vs-constructor-string-or-number-1519142623570
REMARQUE: L'ordre dans lequel les fonctions sont répertoriées bascule entre les images!
Chrome 64.0.3282.167 (64 bits, Windows)
Firefox 59.0b10 (64 bits, Windows)
REMARQUE: L'ordre dans lequel les fonctions sont répertoriées bascule entre les images!
la source
Utilisez instanceof car si vous changez le nom de la classe, vous obtiendrez une erreur de compilation.
la source
la source
Venant d'une éducation OO stricte, j'irais
Les cordes sont sujettes à mon horrible orthographe ou à d'autres fautes de frappe. De plus, je sens que ça se lit mieux.
la source
Bien que instanceof puisse être un peu plus rapide que typeof , je préfère le second en raison d'une telle magie possible:
la source
Un autre cas est que vous ne pouvez collationner qu'avec
instanceof
- cela renvoie vrai ou faux. Avectypeof
vous pouvez obtenir le type de quelque chose fournila source
avec les performances à l'esprit, vous feriez mieux d'utiliser typeof avec un matériel typique, si vous créez un script avec une boucle de 10 millions d'itérations l'instruction: typeof str == 'string' prendra 9 ms tandis que 'string' instanceof String prendra 19 ms
la source
Bien sûr, cela compte ........!
Passons en revue ces exemples: dans notre exemple, nous allons déclarer la fonction de deux manières différentes.
Nous utiliserons les deux
function declaration
et Function Constructor . Nous verrons commenttypeof
etinstanceof
se comportera dans ces deux scénarios différents.Créer une fonction en utilisant la déclaration de fonction:
Une explication possible de ce résultat différent est que, comme nous avons fait une déclaration de fonction, nous
typeof
pouvons comprendre qu'il s'agit d'une fonction.Parce quetypeof
vérifie si l'expression sur quel typeof fonctionne, dans notre cas, la méthode d'appel implémentée ou non . S'il implémente une méthode, c'est une fonction, sinon pas. Pour plus de précision, vérifiez la spécification ecmascript pour typeof .MyFunc
Call
Créer une fonction à l'aide du constructeur de fonction:
Ici ,
typeof
affirme queMyFunc2
est une fonction aussi bien que lainstanceof
operator.We savent déjàtypeof
vérifier siMyFunc2
mis en œuvre laCall
méthode ou not.AsMyFunc2
est une fonction et il met en œuvre lacall
méthode, voilà commenttypeof
sait que c'est un function.On d' autre part, nous avons utiliséfunction constructor
pour créerMyFunc2
, il devient une instance deFunction constructor
. C'est pourquoiinstanceof
se résout également àtrue
.Qu'est-ce qui est plus sûr à utiliser?
Comme nous pouvons le voir dans les deux cas, l'
typeof
opérateur peut affirmer avec succès que nous avons affaire à une fonction ici, elle est plus sûre queinstanceof
.instanceof
échouera en cas defunction declaration
parce quefunction declarations
ne sont pas une instance deFunction constructor
.Meilleur entrainement :
Comme l'a suggéré Gary Rafferty , la meilleure façon devrait être d'utiliser à la fois typeof et instanceof ensemble.
la source
Pour être très précis, instanceof doit être utilisé lorsque la valeur est créée via le constructeur (généralement des types personnalisés), par exemple
alors que typeof pour vérifier les valeurs créées juste par des affectations pour par exemple
la source
pas besoin de vous submerger avec une tonne d'exemples ci-dessus, gardez juste à l'esprit deux points de vue:
typeof var;
est un opérateur unaire retournera le type d'origine ou le type racine de var. de sorte qu'il sera de retour types primitifs (string
,number
,bigint
,boolean
,undefined
, etsymbol
) ou deobject
type.dans le cas d'objets de niveau supérieur, comme des objets intégrés (String, Number, Boolean, Array ..) ou des objets complexes ou personnalisés, tous sont de
object
type racine, mais le type d'instance basé sur eux est variable (comme la classe OOP concept d'héritage), icia instanceof A
- un opérateur binaire - vous aidera, il passera par la chaîne du prototype pour vérifier si le constructeur de l'opérande droit (A) apparaît ou non.donc à chaque fois que vous voulez vérifier "type racine" ou travailler avec une variable primitive - utilisez "typeof", sinon utilisez "instanceof".
null
est un cas spécial, qui est apparemment primitif, mais qui est en effet un cas spécial pour objet. Utilisera === null
pour vérifier null à la place.d'autre part,
function
est également un cas spécial, qui est un objet intégré maistypeof
retournefunction
comme vous pouvez le voir, vous
instanceof
devez passer par la chaîne de prototype en attendant,typeof
vérifiez simplement le type de racine une fois afin qu'il soit facile de comprendre pourquoitypeof
est plus rapide queinstanceof
la source
Selon la documentation MDN sur typeof , les objets instanciés avec le "nouveau" mot-clé sont de type "objet":
La documentation sur instanceof indique que:
Donc, si l'on veut vérifier par exemple que quelque chose est une chaîne, peu importe comment elle a été créée, l'approche la plus sûre serait d'utiliser
instanceof
.la source