JavaScript isPrototypeOf vs instanceof usage

JavaScript isPrototypeOf vs instanceof usage,javascript,Javascript,假设我们有以下情况: function Super() { // init code } function Sub() { Super.call(this); // other init code } Sub.prototype = new Super(); var sub = new Sub(); 然后,在ocde的其他部分,我们可以使用以下任一项检查关系: sub instanceof Super; 或 无论哪种方式,我们都需要对象(sub

假设我们有以下情况:

function Super() {
      // init code
}

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

Sub.prototype = new Super();

var sub = new Sub();
然后,在ocde的其他部分,我们可以使用以下任一项检查关系:

sub instanceof Super;   

无论哪种方式,我们都需要对象(sub)和父构造函数(Super)。那么,有什么理由让你用一个来对抗另一个吗?是否还有其他更明确的区别

我已经仔细阅读了,但没有找到足够具体的答案。

想象一下,您的代码中没有使用构造函数,而是使用构造函数生成具有特定原型的对象。您的程序可能被设计为完全不使用构造函数:

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

在这里,您没有可用于
instanceof
的构造函数。只能使用
subto.isPrototypeOf(sub)

使用构造函数时,差别不大
instanceof
可能更干净一些。但当你不

var human = {mortal: true}
var socrates = Object.create(human);
human.isPrototypeOf(socrates); //=> true
socrates instanceof human; //=> ERROR!
因此,
isPrototypeOf
更为通用

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
你明白吗,我的朋友:)-根据这句话很简单

isPrototypeOf()
不同于
instanceof
运算符。在函数的表达式
对象实例
中,对象原型链是根据
affunction.prototype
检查的,而不是根据
affunction
本身检查的

补足

构造函数的对象实例

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:“instanceof”的右侧不可调用

instanceof
需要右边的值才能调用,这意味着它必须是一个函数(MDN将其作为构造函数调用)

instanceof
测试对象的原型链中是否存在
constructor.prototype


但是
isPrototypeOf()
没有这样的限制。
instanceof
检查
superprotof.prototype
isPrototypeOf()
直接检查
superprotof

谢谢你的回答,我有一个快速跟进:既然isPrototypeOf似乎在所有情况下都能工作,为什么我们需要instanceof?它是历史性的还是有性能优势,还是其他原因?@user1689498仅仅是因为
isPrototypeOf
后来才实现。@user1689498:
instanceof
我认为比较老,看起来类似于Java,这在最初引入JavaScript时是一件大事。它也比较干净。但是是的,
isPrototypeOf
是更普遍的有用的一个。可能的重复基于OP的评论,我想说这个问题更接近于“为什么我们需要
实例的
?”,但我同意它可能已经足够接近了。可能的重复很棒!)但有一件事。本例中的«人»应为«人»。我的意思是它应该是一个类(所有人),而不是一个实例(人)。@NaeelMaqsudov:注意语言之间的类比。Javascript没有类。即使在ES6中添加了
class
syntactical sugar的讽刺,该语言仍然不会有真正类似Java类的东西。原型遗传与经典遗传有一些相似之处,但相似之处比较粗糙。在任何继承方式中,都会有这样一个对象——可能是构造函数的原型。但是请注意:
var naeel=Object.create(human);人类的奈尔实例;//=>正确
。这去掉了一些构造函数的糖分。对不起,剪切粘贴错误<代码>人类的naeel实例;//=>错误。
但是
人的.prototypOf(naeel);//=>真的
。哇。我想我需要一些咖啡因
isPrototypeOf
@NaeelMaqsudov:最重要的是,请注意,尽管历史上构造函数的函数早于
Object.create
,但后者才是更基本的构造。构造函数可以很容易地构建在
对象的顶部。create
,这是基本行为,而
instanceOf
可以构建在
isPrototypeOf
的顶部,但反过来却不是真的,或者至少没有明显的解决方案。使用这种机制,您可以像使用构造函数一样轻松地宣称所有此类构造对象都是“人类”对象。我不确定您试图传达的内容以及它与问题的关系。你能解释一下吗?通过“instanceof”-操作符和Object.isPrototypeOf()-methode-或者?
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 );