Rom*_*din 1 javascript inheritance object
我只是无法理解,为什么在对象继承中“instanceof”无法将“子”对象评估为父原型的实例。例如:
function Parent(property) {
this.property = property;
}
function Child(property) {
Parent.call(property);
}
const child = new Child("");
console.log(child instanceof Child); // of course, true
console.log(child instanceof Parent); // false. But why???
Run Code Online (Sandbox Code Playgroud)
至于类的继承(或者说JS中被认为是类的东西),情况就不同了:
class Parent {
constructor(property) {
this.property = property;
}
}
class Child extends Parent {
constructor(property) {
super(property);
}
}
const child = new Child("");
console.log(child instanceof Child); // true
console.log(child instanceof Parent); // also true!!!
Run Code Online (Sandbox Code Playgroud)
造成这种差异的原因是什么?是否可以创建子对象,以便将它们正确地识别为其父原型的实例(无需求助于类)?
你的第一个例子很简单,与 Javascript 中“原型继承”的工作方式相差甚远。
一方面,Parent.call(property)这肯定不是你的意思。此调用Parent将其this设置为property,并且没有传递任何参数,这绝对不是您想要的。我怀疑你的意思是Parent.call(this, property)- 它调用Parent与this传递给相同的内容Child,并传递property参数。但这与“继承”无关。
instanceof运算符只是检查对象的“原型链”,以查看相关对象(prototype您正在测试的“类”的属性)是否出现在任何位置。操纵对象影响instanceof操作者的唯一方法是改变原型链。
有很多方法可以做到这一点,但“伪造”JS(ES6 之前)中基于类的继承之类的标准方法是这样的:
function Parent(property) {
this.property = property;
}
function Child(property) {
}
Child.prototype = Object.create(Parent.prototype);
const child = new Child("");
console.log(child instanceof Child);
console.log(child instanceof Parent);Run Code Online (Sandbox Code Playgroud)
它手动使所有对象从Childdelegate 构造为Object.create(Parent.prototype),它本身就是一个“继承”自 的对象(否则完全是空的并且没有特殊属性)Parent.prototype。因此,现在当instanceof检查原型链时,它会找到它正在寻找的内容,因此返回true,正如您从上面的代码片段中看到的那样。
当然,如果你确实想要在 JS 中基于类的继承(我个人不推荐,但肯定很流行),ES6 语法class提供了更好的语法糖,因此你不必手动弄乱原型链如上。但请注意,这本质上就是 ES6 类“幕后”发生的事情。
我强烈推荐这本书(可以免费在线阅读),以获得对这一切的更深入的解释。第 5 章是与此背景最相关的章节。