Est a instanceof b
TOUJOURS la même chose que b.prototype.isPrototypeOf(a)
?
Non, a instanceof b
ne se comportera pas toujours de la même manière que b.prototype.isPrototypeOf(a)
.
Réponse de la CMS a souligné qu'ils diffèrent dans ce qu'ils sont (l'un est un opérateur et l'autre est une méthode intégrée disponible sur l'objet Object.prototype
objet). C'est correct, mais il y a aussi des cas particuliers pour lesquels la fonction a instanceof b
se traduira par un TypeError
tandis que b.prototype.isPrototypeOf(a)
fonctionnera très bien et vice versa.
Différence 1
Le côté droit de instanceof
est censé être une fonction de construction.
Si b
n'est pas une fonction :
-
a instanceof b
se traduira par un TypeError
.
-
b.prototype.isPrototypeOf(a)
fonctionnera très bien.
const b = {
prototype: {}
};
const a = Object.create( b.prototype );
console.log( b.prototype.isPrototypeOf(a) ); // true
console.log( a instanceof b ); // TypeError: Right-hand side of 'instanceof' is not callable
Différence n°2
Lorsque vous utilisez b.prototype.isPrototypeOf(a)
, b.prototype
devrait hériter de Object.prototype
:
Si b.prototype
n'a pas accès à la Object.prototype.isPrototypeOf()
méthode :
-
b.prototype.isPrototypeOf(a)
se traduira par un TypeError
.
-
a instanceof b
fonctionnera très bien.
function B() {};
B.prototype = Object.create( null );
const a = new B();
console.log( a instanceof B ); // true
console.log( B.prototype.isPrototypeOf(a) ) // TypeError: B.prototype.isPrototypeOf is not a function
Différence n°3
Si le côté droit de instanceof
est une fonction liée, elle est traitée de manière équivalente à sa fonction cible.
Si b est une fonction liée :
-
a instanceof b
fonctionnera très bien.
-
b.prototype.isPrototypeOf(a)
se traduira par un TypeError
(les fonctions liées n'ont pas de prototype
propriété).
function B() {};
const BoundB = B.bind( null );
const a = new B();
console.log( a instanceof BoundB ); // true
console.log( BoundB.prototype.isPrototypeOf(a) ) // TypeError: Cannot read property 'isPrototypeOf' of undefined
Conclusion
- Si vous avez affaire à un héritage prototypique établi par l'intermédiaire de
Object.create()
sans l'utilisation de constructeurs, vous devriez probablement utiliser la fonction Object.prototype.isPrototypeOf()
(en effet, les cas d'utilisation de la méthode instanceof
sont plus restreints en ce sens que instanceof
s'attend à ce que son paramètre du côté droit soit une fonction constructeur).
- Si vous avez affaire à des constructeurs, vous serez légèrement plus en sécurité en utilisant l'option
instanceof
(vous serez en mesure de couvrir les fonctions liées ainsi que les cas dans lesquels Object.prototype
ne se trouve pas dans la chaîne des prototypes de Constructor.prototype
).
0 votes
Bien que vous puissiez toujours utiliser
instanceof
(avec des constructeurs en RHS), tous les objets ne peuvent pas hériter deObject.prototype
.Object.create(null) instanceof Something
y({}).instanceOf({prototype:Something.prototype})
fonctionnera (et donnerafalse
) où l'inverse échouerait.