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 );