Question

Le mot-clé instanceof JavaScript peut être assez déroutant quand il est d'abord rencontré, que les gens ont tendance à penser que JavaScript n'est pas un langage de programmation orienté objet.

  • Qu'est-ce?
  • Quels problèmes faut-il résoudre?
  • Quand est-il approprié et quand ne pas?
Était-ce utile?

La solution

instanceof

L'opérande côté gauche (LHS) est l'objet réel testé à l'opérande Côté droit (RHS) qui est le constructeur réelle d'une classe. La définition de base est:

Checks the current object and returns true if the object
is of the specified object type.

Voici quelques bons exemples et voici un exemple pris directement à partir de site développeur de Mozilla :

var color1 = new String("green");
color1 instanceof String; // returns true
var color2 = "coral"; //no type specified
color2 instanceof String; // returns false (color2 is not a String object)

Une chose intéressante à mentionner est instanceof évalue true si l'objet hérite du prototype du classe:

var p = new Person("Jon");
p instanceof Person

C'est p instanceof Person est vrai que p hérite de Person.prototype.

Par la demande de l'OP

J'ai ajouté un petit exemple avec quelques exemples de code et une explication.

Lorsque vous déclarez une variable que vous lui donnez un type spécifique.

Par exemple:

int i;
float f;
Customer c;

Le spectacle ci-dessus vous quelques variables, à savoir i, f et c. Les types sont integer, float et un Customer défini par l'utilisateur type de données. Les types tels que ci-dessus pourraient être pour toutes les langues, pas seulement JavaScript. Cependant, avec JavaScript lorsque vous déclarez une variable que vous ne définissez pas explicitement un type, var x, x peut être un nombre / string / un type de données défini par l'utilisateur. Alors qu'est-ce instanceof fait est-il vérifie l'objet pour voir si elle est du type spécifié ci-dessus afin de prendre l'objet Customer nous pourrions faire:

var c = new Customer();
c instanceof Customer; //Returns true as c is just a customer
c instanceof String; //Returns false as c is not a string, it's a customer silly!

Au-dessus, nous avons vu que c a été déclarée avec le Customer de type. Nous avons new'd et vérifié si elle est de type Customer ou non. Bien sûr, est-il retourne vrai. Ensuite, en utilisant encore l'objet Customer, nous vérifions si elle est un String. Non, certainement pas un String nous newed un objet Customer pas un objet String. Dans ce cas, il retourne faux.

Il est vraiment aussi simple que cela!

Autres conseils

Il y a un aspect important de InstanceOf qui ne semble pas être couvert dans l'un des commentaires jusqu'ici: l'héritage. Une variable qui est évaluée par l'utilisation de instanceof pourrait retourner vrai pour plusieurs « types » en raison de l'héritage prototypal.

Par exemple, nous allons définir un type et un sous-type:

function Foo(){ //a Foo constructor
    //assign some props
    return this;
}

function SubFoo(){ //a SubFoo constructor
    Foo.call( this ); //inherit static props
    //assign some new props
    return this;
}

SubFoo.prototype = Object.create(Foo.prototype); // Inherit prototype
SubFoo.prototype.constructor = SubFoo;

Maintenant que nous avons deux ou trois « classes » permet de faire certains cas, et savoir ce qu'ils sont les cas de:

var 
    foo = new Foo()
,   subfoo = new SubFoo()
;

alert( 
    "Q: Is foo an instance of Foo? "
+   "A: " + ( foo instanceof Foo ) 
); // -> true

alert( 
    "Q: Is foo an instance of SubFoo? " 
+   "A: " + ( foo instanceof SubFoo ) 
); // -> false

alert( 
    "Q: Is subfoo an instance of Foo? "
+   "A: " + ( subfoo instanceof Foo ) 
); // -> true

alert( 
    "Q: Is subfoo an instance of SubFoo? "
+   "A: " + ( subfoo instanceof SubFoo ) 
); // -> true

alert( 
    "Q: Is subfoo an instance of Object? "
+   "A: " + ( subfoo instanceof Object ) 
); // -> true

Voir cette dernière ligne? Tous les appels « nouveaux » à une fonction retourne un objet qui hérite de l'objet. Cela est vrai même en utilisant un raccourci de création d'objets:

alert( 
    "Q: Is {} an instance of Object? "
+   "A: " + ( {} instanceof Object ) 
); // -> true

Et la « classe » eux-mêmes définitions? Que sont-ils des cas de?

alert( 
    "Q: Is Foo an instance of Object? "
+   "A:" + ( Foo instanceof Object) 
); // -> true

alert( 
    "Q: Is Foo an instance of Function? "
+   "A:" + ( Foo instanceof Function) 
); // -> true

Je pense que la compréhension que tout objet peut être une instance de multiples types est important, puisque vous mon (à tort) supposons que vous pouvez faire la différence entre, par exemple et de l'objet et une fonction par l'utilisation de instanceof. Comme ce dernier exemple montre clairement une fonction un objet.

Il est également important si vous utilisez des modèles d'héritage et que vous voulez confirmer la descendance d'un objet par des méthodes autres que le canard dactylographie.

L'espoir qui aide qui entend explorer instanceof.

Les autres réponses ici sont corrects, mais ils ne reçoivent pas la façon dont instanceof fonctionne réellement, ce qui peut intéresser certains avocats de la langue là-bas.

Chaque objet JavaScript a un prototype, accessible par la propriété __proto__. Les fonctions ont également une propriété prototype, qui est le __proto__ initial pour tous les objets créés par eux. Lorsqu'une fonction est créée, elle est donnée un objet unique pour prototype. L'opérateur utilise cette instanceof unique pour vous donner une réponse. Voici ce que instanceof pourrait ressembler si vous l'avez écrit en fonction.

function instance_of(V, F) {
  var O = F.prototype;
  V = V.__proto__;
  while (true) {
    if (V === null)
      return false;
    if (O === V)
      return true;
    V = V.__proto__;
  }
}

Ceci est essentiellement paraphrase édition ECMA-262 5.1 (également connu sous le nom ES5), section 15.3.5.3.

Notez que vous pouvez réaffecter un objet à la propriété prototype d'une fonction, et vous pouvez réattribuer après sa construction, la propriété __proto__ d'un objet. Cela vous donnera des résultats intéressants:

function F() { }
function G() { }
var p = {};
F.prototype = p;
G.prototype = p;
var f = new F();
var g = new G();

f instanceof F;   // returns true
f instanceof G;   // returns true
g instanceof F;   // returns true
g instanceof G;   // returns true

F.prototype = {};
f instanceof F;   // returns false
g.__proto__ = {};
g instanceof G;   // returns false

Je pense qu'il est intéressant de noter que instanceof est définie par l'utilisation du mot-clé « nouveau » lors de la déclaration de l'objet. Dans l'exemple de Jonh;

var color1 = new String("green");
color1 instanceof String; // returns true
var color2 = "coral";
color2 instanceof String; // returns false (color2 is not a String object)

Ce qu'il ne mentionne pas est ceci:

var color1 = String("green");
color1 instanceof String; // returns false

Spécification « nouveau » en fait copié l'état final de la fonction constructeur String dans le var color1, plutôt que de la mise à la valeur de retour. Je pense que cette montre mieux ce que le nouveau mot-clé fait;

function Test(name){
    this.test = function(){
        return 'This will only work through the "new" keyword.';
    }
    return name;
}

var test = new Test('test');
test.test(); // returns 'This will only work through the "new" keyword.'
test // returns the instance object of the Test() function.

var test = Test('test');
test.test(); // throws TypeError: Object #<Test> has no method 'test'
test // returns 'test'

Utilisation de « nouveau » attribue la valeur de « cette » à l'intérieur de la fonction à la var déclarée, sans utiliser affecte la valeur de retour à la place.

Et vous pouvez l'utiliser pour le traitement des erreurs et le débogage, comme ceci:

try{
    somefunction();
} 
catch(error){
    if (error instanceof TypeError) {
        // Handle type Error
    } else if (error instanceof ReferenceError) {
        // Handle ReferenceError
    } else {
        // Handle all other error types
    }
}
//Vehicle is a function. But by naming conventions
//(first letter is uppercase), it is also an object
//constructor function ("class").
function Vehicle(numWheels) {
    this.numWheels = numWheels;
}

//We can create new instances and check their types.
myRoadster = new Vehicle(4);
alert(myRoadster instanceof Vehicle);
  

Qu'est-ce?

Javascript est un langage prototypique qui signifie qu'il utilise des prototypes « héritage ». les tests d'opérateur instanceof si un prototype de fonction constructeur de propertype est présent dans la chaîne de __proto__ d'un objet. Cela signifie qu'il fera ce qui suit (en supposant que TestObj est un objet de fonction):

obj instanceof testObj;
  1. Vérifiez si le prototype de l'objet est égal au prototype du constructeur:. obj.__proto__ === testObj.prototype >> si cela est true instanceof retournera true
  2. monterai la chaîne de prototype. Par exemple:. obj.__proto__.__proto__ === testObj.prototype >> si cela est true instanceof retournera true
  3. répétera l'étape 2 jusqu'à ce que le prototype complet de l'objet est inspecté. Si nulle part sur la chaîne de prototype de l'objet est apparié avec testObj.prototype alors opérateur instanceof retournera false.

Exemple:

function Person(name) {
  this.name = name;
}
var me = new Person('Willem');

console.log(me instanceof Person); // true
// because:  me.__proto__ === Person.prototype  // evaluates true

console.log(me instanceof Object); // true
// because:  me.__proto__.__proto__ === Object.prototype  // evaluates true

console.log(me instanceof Array);  // false
// because: Array is nowhere on the prototype chain

  

Quels problèmes faut-il résoudre?

Il a résolu le problème de vérifier facilement si un objet dérive d'un certain prototype. Par exemple, lorsqu'une fonction d'un objet qui reçoit peut avoir différents prototypes. Puis, avant d'utiliser des méthodes de la chaîne prototype, nous pouvons utiliser l'opérateur instanceof pour vérifier si les ces méthodes sont l'objet.

Exemple:

function Person1 (name) {
  this.name = name;
}

function Person2 (name) {
  this.name = name;
}

Person1.prototype.talkP1 = function () {
  console.log('Person 1 talking');
}

Person2.prototype.talkP2 = function () {
  console.log('Person 2 talking');
}


function talk (person) {
  if (person instanceof Person1) {
    person.talkP1();
  }
  
  if (person instanceof Person2) {
    person.talkP2();
  }
  
  
}

const pers1 = new Person1 ('p1');
const pers2 = new Person2 ('p2');

talk(pers1);
talk(pers2);

Ici, dans la fonction talk() premier est vérifié si le prototype est situé sur l'objet. Après cela, la méthode appropriée est choisi pour exécuter. Ne pas faire cette vérification pourrait donner lieu à l'exécution d'une méthode qui n'existe pas et donc une erreur de référence.

  

Quand est-il approprié et quand ne pas?

Nous avons un peu déjà allés à ce sujet. Utilisez-le quand vous avez besoin de vérifier le prototype d'un objet avant de faire quelque chose avec elle.

Sur la question "Quand est-il approprié et quand ne pas?", Mes 2 cents:

instanceof est rarement utile dans le code de production, mais utile dans les tests où vous voulez affirmer que votre code renvoie / crée des objets des types corrects. En étant explicite sur les types d'objets que votre code Reprise / création, vos tests deviennent plus puissants comme un outil pour comprendre et documenter votre code.

instanceof est juste du sucre syntaxique pour isPrototypeOf:

function Ctor() {}
var o = new Ctor();

o instanceof Ctor; // true
Ctor.prototype.isPrototypeOf(o); // true

o instanceof Ctor === Ctor.prototype.isPrototypeOf(o); // equivalent

instanceof dépend juste du prototype d'un constructeur d'un objet.

Un constructeur est juste une fonction normale. Au sens strict, il est un objet de fonction, puisque tout est un objet en Javascript. Et cet objet de fonction a un prototype, parce que 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 veut dire être dans la chaîne de prototype d'un autre objet fait l'objet d'un prototype:

function f() {} //  ordinary function
var o = {}, // ordinary object
 p;

f.prototype = o; // oops, o is a prototype now
p = new f(); // oops, f is a constructor now

o.isPrototypeOf(p); // true
p instanceof f; // true

L'opérateur instanceof doit être évitée car elle feint des classes, qui n'existent pas en Javascript. Malgré le mot-clé class pas ES2015 non plus, puisque class est à nouveau juste du sucre syntaxique pour ... mais c'est une autre histoire.

Je viens de trouver une application dans le monde réel et utilisera plus souvent maintenant, je pense.

Si vous utilisez des événements jQuery, parfois vous voulez écrire une fonction plus générique qui peut également être appelé directement (sans événement). Vous pouvez utiliser instanceof pour vérifier si le premier paramètre de votre fonction est une instance de jQuery.Event et réagir de manière appropriée.

var myFunction = function (el) {                
    if (el instanceof $.Event) 
        // event specific code
    else
        // generic code
};

$('button').click(recalc);    // Will execute event specific code
recalc('myParameter');  // Will execute generic code

Dans mon cas, la fonction nécessaire pour calculer quelque chose soit pour tous (par événement clic sur un bouton) ou un seul élément spécifique. Le code je:

var recalc = function (el) { 
    el = (el == undefined || el instanceof $.Event) ? $('span.allItems') : $(el);
    // calculate...
};
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top