简体   繁体   English

JavaScript isPrototypeOf vs instanceof用法

[英]JavaScript isPrototypeOf vs instanceof usage

Suppose we have the following: 假设我们有以下内容:

function Super() {
      // init code
}

function Sub() {
      Super.call(this);
      // other init code
}

Sub.prototype = new Super();

var sub = new Sub();

Then, in some other part of our ocde, we can use either of the following to check for the relationship: 然后,在我们ocde的其他部分,我们可以使用以下任一方法来检查关系:

sub instanceof Super;   

or 要么

Super.prototype.isPrototypeOf( sub )

Either way, we need to have both the object (sub), and the parent constructor (Super). 无论哪种方式,我们都需要同时拥有对象(sub)和父构造函数(Super)。 So, is there any reason why you'd use one vs the other? 那么,你有没有理由使用其中一个? Is there some other situation where the distinction is more clear? 还有其他一些区别更明确的情况吗?

I've already carefully read 2464426 , but didn't find a specific enough answer. 我已经仔细阅读了2464426 ,但没有找到足够具体的答案。

Imagine you don't use constructors in your code, but instead use Object.create to generate objects with a particular prototype. 想象一下,您不在代码中使用构造函数 ,而是使用Object.create生成具有特定原型的对象。 Your program might be architected to use no constructors at all: 您的程序可能被架构为根本不使用构造函数:

var superProto = {
    // some super properties
}

var subProto = Object.create(superProto);
subProto.someProp = 5;

var sub = Object.create(subProto);

console.log(superProto.isPrototypeOf(sub));  // true
console.log(sub instanceof superProto);      // TypeError

Here, you don't have a constructor function to use with instanceof . 在这里,您没有与instanceof一起使用的构造函数。 You can only use subProto.isPrototypeOf(sub) . 您只能使用subProto.isPrototypeOf(sub)

It makes little difference when you use constructor functions. 使用构造函数时,它几乎没有什么区别。 instanceof is a little cleaner, perhaps. 也许, instanceof有点干净。 But when you don't...: 但是当你不......时:

var human = {mortal: true}
var socrates = Object.create(human);
human.isPrototypeOf(socrates); //=> true
socrates instanceof human; //=> ERROR!

So isPrototypeOf is more general. 所以isPrototypeOf更通用。

According to this MDN Ref : 根据MDN Ref

isPrototypeOf() differs from the instanceof operator. isPrototypeOf()instanceof运算符不同。 In the expression object instanceof AFunction , the object prototype chain is checked against AFunction.prototype , not against AFunction itself. 在表达式object instanceof AFunction ,对象原型链将针对AFunction.prototype进行检查,而不是针对AFunction本身。

var neuesArray = Object.create(Array);

Array.isPrototypeOf(neuesArray);            // true
neuesArray instanceof Array                 // false
neuesArray instanceof Object                // true
Array.isArray(neuesArray);                  // false
Array.prototype.isPrototypeOf(neuesArray);  // false
Object.prototype.isPrototypeOf(neuesArray); // true

Do you understand my friend :) - is simple 你了解我的朋友:) - 很简单

Just complement @apsillers's answer 只是补充@ apsillers的答案

object instanceof constructor

var superProto = {}

// subProto.__proto__.__proto__ === superProto
var subProto = Object.create(superProto);
subProto.someProp = 5;
// sub.__proto__.__proto__ === subProto
var sub = Object.create(subProto);

console.log(superProto.isPrototypeOf(sub)); // true
console.log(sub instanceof superProto); // TypeError: Right-hand side of 'instanceof' is not callable

// helper utility to see if `o1` is
// related to (delegates to) `o2`
function isRelatedTo(o1, o2) {
  function F(){}
  F.prototype = o2;
  // ensure the right-hand side of 'instanceof' is callable
  return o1 instanceof F; 
}
isRelatedTo( b, a ); 

TypeError: Right-hand side of 'instanceof' is not callable TypeError:'instanceof'的右侧不可调用

instanceof need the right-hand value to be callable, which means it must be a function(MDN call it as the constructor) instanceof需要右侧值可调用,这意味着它必须是一个函数(MDN将其称为构造函数)

and instanceof tests the presence of constructor.prototype in object's prototype chain. instanceof测试对象原型链中constructor.prototype的存在。

but isPrototypeOf() don't have such limit. isPrototypeOf()没有这样的限制。 While instanceof checks superProto.prototype , isPrototypeOf() checks superProto directly. instanceof检查superProto.prototypeisPrototypeOf()直接检查superProto

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM