Quelle est la différence entre isPrototypeOf et instanceof en Javascript?

dans certains de mes anciens codes, j'utilise ce qui suit:

Object.prototype.instanceOf = function( iface )
{
 return iface.prototype.isPrototypeOf( this );
};

Puis-je faire (par exemple)

[].instanceOf( Array )

cela fonctionne, mais il semble que la suivante ferait la même chose:

[] instanceof Array

maintenant, sûrement ce n'est qu'un exemple très simple. Ma question est donc:

est-ce que a instanceof b est toujours la même chose que b.prototype.isPrototypeOf(a) ?

37
demandé sur Keith Thompson 2010-03-17 20:28:45

2 réponses

Oui, ils font la même chose, tous les deux parcourent la chaîne du prototype à la recherche d'un objet spécifique.

la différence entre les deux est ce qu'ils sont , et comment vous les utilisez, par exemple le isPrototypeOf est une fonction disponible sur l'objet Object.prototype , il vous permet de tester si un objet spécifique est dans la chaîne prototype d'un autre, puisque cette méthode est défini sur Object.prototype , il est disponible pour tous les objets.

instanceof est un opérateur et il attend deux opérandes, un objet et un fonction constructeur , il va tester si la fonction réussie prototype propriété existe sur la chaîne de l'objet (via le [[HasInstance]](V) opération interne, disponible uniquement dans les objets de fonction).

Par exemple:

function A () {
  this.a = 1;
}
function B () {
  this.b = 2;
}
B.prototype = new A();
B.prototype.constructor = B;

function C () {
  this.c = 3;
}
C.prototype = new B();
C.prototype.constructor = C;

var c = new C();

// instanceof expects a constructor function

c instanceof A; // true
c instanceof B; // true
c instanceof C; // true

// isPrototypeOf, can be used on any object
A.prototype.isPrototypeOf(c); // true
B.prototype.isPrototypeOf(c); // true
C.prototype.isPrototypeOf(c); // true
27
répondu CMS 2010-03-17 18:32:58

L'ordre de priorité et la véracité de L'opérateur diffèrent car l'un est une expression et l'autre est un appel de méthode. Une chose à souligner est que les deux traversent la chaîne du prototype , de sorte que vous ne pouvez pas supposer qu'il ya une correspondance un-à-un entre un prototype correspondant et l'objet en question:

var i = 0;

function foo()
{
console.log("foo");
console.log(i++ + ": " + Object.prototype.isPrototypeOf(Object) ) //true
console.log(i++ + ": " + Function.prototype.isPrototypeOf(Function) ) //true

console.log(i++ + ": " + Function.prototype.isPrototypeOf(Function) ) //true
console.log(i++ + ": " + Function.prototype.isPrototypeOf(Object) ) //true

console.log(i++ + ": " + RegExp.prototype.isPrototypeOf( RegExp(/foo/) ) ) //true
console.log(i++ + ": " + Object.prototype.isPrototypeOf( RegExp(/foo/) ) ) //true
console.log(i++ + ": " + Function.prototype.isPrototypeOf( RegExp(/foo/) ) ) //false
console.log(i++ + ": " + Object.prototype.isPrototypeOf(Math) ) //true
console.log(i++ + ": " + Math.isPrototypeOf(Math) ) //false
}

function bar()
{
console.log("bar");
console.log(i++ + ": " + (Object instanceof Object) ) //true

console.log(i++ + ": " + (Function instanceof Function) ) //true
console.log(i++ + ": " + (Function instanceof Object) ) //true

console.log(i++ + ": " + (RegExp(/foo/) instanceof RegExp) ) //true
console.log(i++ + ": " + (RegExp(/foo/) instanceof Object)  ) //true
console.log(i++ + ": " + (RegExp(/foo/) instanceof Function) ) //false
console.log(i++ + ": " + (Math instanceof Object) ) //true
console.log(i++ + ": " + (Math instanceof Math) ) //error
}
try
  {
  foo()
  }
catch(e)
  {
  console.log(JSON.stringify(e));
  }
finally
  {
  try
    {
    bar();
    }
  catch(e)
    {
    console.log(JSON.stringify(e));
    }
  }

Références

0
répondu Paul Sweatte 2017-07-26 22:14:54