Le instanceof
mot clé en JavaScript peut être assez déroutant lorsqu'il est rencontré pour la première fois, car les gens ont tendance à penser que JavaScript n'est pas un langage de programmation orienté objet.
- Qu'Est-ce que c'est?
- Quels problèmes cela résout-il?
- Quand est-ce approprié et quand non?
javascript
operators
instanceof
Alon Gubkin
la source
la source
"foo" instanceof String
=> faux,1 instanceof Number
=> faux,{} instanceof Object
=> faux. Tu peux répéter s'il te plait?!"foo" instanceof String => false
est correct, cartypeof "foo" == 'string'
.new String("foo") instanceof String => true
, cartypeof String == 'function'
- vous devez traiter la fonction comme une classe (définition de classe). La variable devientinstanceof
unefunction
(classe) lorsque vous l'assignez en tant quevar v = new AnythingWhatTypeofEqualsFunction()
. La même chose s'applique à1
.typeof 1 == 'number'
- 'nombre' n'est pas 'fonction' :) Suivant -{} instanceof Object
estTRUE
dans le nœud et les navigateurs modernes({}) instanceof Object
reviendratrue
. En fait, le code que vous avez écrit vous donnera une erreur.Réponses:
exemple de
L'opérande côté gauche (LHS) est l'objet réel testé sur l'opérande côté droit (RHS) qui est le constructeur réel d'une classe. La définition de base est:
Voici quelques bons exemples et voici un exemple tiré directement du site de développeur de Mozilla :
Une chose à noter est
instanceof
évaluée à true si l'objet hérite du prototype de la classe:C'est
p instanceof Person
vrai puisquep
hérite dePerson.prototype
.À la demande du PO
J'ai ajouté un petit exemple avec un exemple de code et une explication.
Lorsque vous déclarez une variable, vous lui donnez un type spécifique.
Par exemple:
Le vous montrer ci - dessus certaines variables, à savoir
i
,f
etc
. Les types sontinteger
,float
et défini par l' utilisateurCustomer
type de données. Les types tels que ci-dessus peuvent être pour n'importe quelle langue, pas seulement JavaScript. Cependant, avec JavaScript lorsque vous déclarez une variable, vous ne définissez pas explicitement un typevar x
, x peut être un nombre / chaîne / un type de données défini par l'utilisateur. Donc, qu'estinstanceof
- ce qu'il vérifie l'objet pour voir s'il est du type spécifié,Customer
nous pouvons donc faire de l' objet en haut :Ci-dessus, nous avons vu que cela a
c
été déclaré avec le typeCustomer
. Nous l'avons nouvellement vérifié et vérifié s'il est de typeCustomer
ou non. Bien sûr, cela revient vrai. Puis en utilisant toujours l'Customer
objet, nous vérifions s'il s'agit d'unString
. Non, certainement pas unString
nouvelCustomer
objet, pas unString
objet. Dans ce cas, elle renvoie false.C'est aussi simple que ça!
la source
color1 instanceof String;
cela retournera vrai car color1 est une chaîne.person p = new person()
p est maintenant un type de personne et non un type de chaîne.var zero = 0; alert(zero); zero = "0"; alert(zero)
nous passions d'une primitiveint
à une primitivestring
sans aucun problème.int
en primitifstring
.Il y a une facette importante de l'instance de cela qui ne semble pas être couverte dans aucun des commentaires jusqu'à présent: l'héritage. Une variable en cours d'évaluation à l'aide d'instanceof pourrait retourner vrai pour plusieurs "types" en raison de l'héritage prototypique.
Par exemple, définissons un type et un sous-type:
Maintenant que nous avons quelques "classes", faisons quelques instances et découvrons de quoi il s'agit:
Vous voyez cette dernière ligne? Tous les "nouveaux" appels à une fonction renvoient un objet qui hérite d'Object. Cela est vrai même lorsque vous utilisez un raccourci de création d'objet:
Et qu'en est-il des définitions de "classe" elles-mêmes? De quoi sont-ils des exemples?
Je pense qu'il est important de comprendre que tout objet peut être une instance de types MULTIPLES, car vous pouvez (à tort) supposer que vous pourriez faire la différence entre, disons et objet et une fonction en utilisant
instanceof
. Comme ce dernier exemple montre clairement qu'une fonction est un objet.Ceci est également important si vous utilisez des modèles d'héritage et souhaitez confirmer la descendance d'un objet par des méthodes autres que le typage canard.
J'espère que cela aide quiconque à explorer
instanceof
.la source
SubFoo.prototype = new Foo();
vous pouvez ajouter plus de méthodes, et lesubfoo instanceof Foo
contrôle passera toujours ainsisubfoo instanceof SubFoo
Les autres réponses ici sont correctes, mais elles n'abordent pas le fonctionnement
instanceof
réel, ce qui peut intéresser certains juristes spécialisés en langues.Chaque objet en JavaScript a un prototype, accessible via la
__proto__
propriété. Les fonctions ont également uneprototype
propriété, qui est l'initiale__proto__
de tout objet créé par elles. Lorsqu'une fonction est créée, elle reçoit un objet unique pourprototype
. L'instanceof
opérateur utilise cette unicité pour vous donner une réponse. Voici à quoiinstanceof
pourrait ressembler si vous l'avez écrit en tant que fonction.Il s'agit essentiellement de paraphraser l'ECMA-262 édition 5.1 (également connu sous le nom ES5), section 15.3.5.3.
Notez que vous pouvez réaffecter n'importe quel objet à la
prototype
propriété d' une fonction et vous pouvez réaffecter la__proto__
propriété d' un objet après sa construction. Cela vous donnera des résultats intéressants:la source
__proto__
propriété " " n'est pas autorisée dans IE. Si je me souviens bien, la manipulation directe de la propriété n'est pas non plus incluse dans la spécification ECMA, donc c'est probablement une mauvaise idée de l'utiliser pour une affectation autre que dans des activités académiques.Object.getPrototypeOf(o)
, ce sera le même que celui que__proto__
vous décrivez, mais conforme à ECMAScript.Je pense qu'il vaut la peine de noter que instanceof est défini par l'utilisation du "nouveau" mot clé lors de la déclaration de l'objet. Dans l'exemple de JonH;
Ce qu'il n'a pas mentionné, c'est ceci;
La spécification de "nouveau" a en fait copié l'état final de la fonction constructeur String dans la var color1, plutôt que de simplement la définir sur la valeur de retour. Je pense que cela montre mieux ce que fait le nouveau mot clé;
L'utilisation de "new" affecte la valeur de "this" à l'intérieur de la fonction à la variable déclarée, tandis que ne pas l'utiliser affecte la valeur de retour à la place.
la source
new
avec l'un des types de JavaScript, ce qui rend la réponse acceptée beaucoup plus déroutante pour les débutants.text = String('test')
etoptions = {}
ne vont pas être testés par,instanceof
mais plutôt avectypeof
.Et vous pouvez l'utiliser pour la gestion des erreurs et le débogage, comme ceci:
la source
la source
Javascript est un langage prototypique qui signifie qu'il utilise des prototypes pour «l'héritage». l'
instanceof
opérateur teste si le type deprototype
propriété d' une fonction constructeur est présent dans la__proto__
chaîne d'un objet. Cela signifie qu'il fera ce qui suit (en supposant que testObj est un objet fonction):obj.__proto__ === testObj.prototype
>> si celatrue
instanceof
reviendratrue
.obj.__proto__.__proto__ === testObj.prototype
>> si c'esttrue
instanceof
retournetrue
.testObj.prototype
alors l'instanceof
opérateur retournerafalse
.Exemple:
Il a résolu le problème de vérifier commodément si un objet dérive d'un certain prototype. Par exemple, lorsqu'une fonction reçoit un objet qui peut avoir différents prototypes. Ensuite, avant d'utiliser les méthodes de la chaîne de prototypes, nous pouvons utiliser l'
instanceof
opérateur pour vérifier si ces méthodes se trouvent sur l'objet.Exemple:
Ici dans le
talk()
fonction, on vérifie d'abord si le prototype est situé sur l'objet. Après cela, la méthode appropriée est choisie pour s'exécuter. Ne pas faire cette vérification pourrait entraîner l'exécution d'une méthode qui n'existe pas et donc une erreur de référence.Nous sommes déjà passés par là. Utilisez-le lorsque vous avez besoin de vérifier le prototype d'un objet avant d'en faire quelque chose.
la source
PersonX.prototype.talk
, afin que latalk
fonction puisse simplement faireperson.talk()
.__proto__
dans la documentation, c'est obsolète - écrivez à laObject.getPrototype()
placeSur la question "Quand est-ce approprié et quand non?", Mes 2 cents:
instanceof
est rarement utile dans le code de production, mais utile dans les tests où vous voulez affirmer que votre code retourne / crée des objets des types corrects. En étant explicite sur les types d'objets que votre code retourne / crée, vos tests deviennent plus puissants comme outil pour comprendre et documenter votre code.la source
instanceof
est juste du sucre syntaxique pourisPrototypeOf
:instanceof
dépend juste du prototype d'un constructeur d'un objet.Un constructeur n'est qu'une fonction normale. À proprement parler, c'est un objet fonction, car tout est un objet en Javascript. Et cet objet fonction a un prototype, car chaque fonction a un prototype.
Un prototype est juste un objet normal, qui est situé dans la chaîne de prototype d'un autre objet. Cela signifie que le fait d'être dans la chaîne de prototypes d'un autre objet fait d'un objet un prototype:
L'
instanceof
opérateur doit être évité car il simule des classes qui n'existent pas en Javascript. Malgré leclass
mot - clé qui n'est pas non plus dans ES2015, puisqueclass
c'est encore du sucre syntaxique pour ... mais c'est une autre histoire.la source
instanceof
est toujours dérivé deisPrototypeOf
. J'appelle ce sucre syntaxique. Et votre source MDN est une blague, n'est-ce pas?instanceof
ne fait pas la même chose queisPrototypeOf
. C'est tout.Je viens de trouver une application réelle et je vais l'utiliser plus souvent maintenant, je pense.
Si vous utilisez des événements jQuery, vous souhaitez parfois écrire une fonction plus générique qui peut également être appelée directement (sans événement). Vous pouvez utiliser
instanceof
pour vérifier si le premier paramètre de votre fonction est une instance dejQuery.Event
et réagir de manière appropriée.Dans mon cas, la fonction avait besoin de calculer quelque chose soit pour tous (via l'événement click sur un bouton), soit pour un seul élément spécifique. Le code que j'ai utilisé:
la source