简体   繁体   English

JavaScript 多级继承和 isPrototypeOf

[英]JavaScript Multi-level inheritance and isPrototypeOf

I have a multi-level inheritance implemented in JavaScript like below我在 JavaScript 中实现了多级继承,如下所示

function MovingObject(){

}

function Vehicle(){

}
Vehicle.prototype = Object.create(MovingObject);

function Car(){

}
Car.prototype = Object.create(Vehicle);

var c = new Car();

Car is child of Vehicle which in turn is child of MovingObject, so I am expecting Car to be indirect child of MovingObject. Car 是 Vehicle 的孩子,而 Vehicle 又是MovingObject 的孩子,所以我希望Car 是MovingObject 的间接孩子。

Below statement returns true indicating Car is direct child of Vehicle下面的语句返回 true 表示 Car 是 Vehicle 的直接子代

Vehicle.isPrototypeOf(c);

But, below statement does not return true但是,下面的语句不返回 true

MovingObject.isPrototypeOf(c);

Any idea why it does not return true , and how to get it to return true ?知道为什么它不返回 true ,以及如何让它返回 true吗?

This is a common issue about JavaScript.这是 JavaScript 的一个常见问题。

MovingObject or Vehicle are constructor functions but they're not the prototypes. MovingObjectVehicle构造函数,但它们不是原型。

That is, you should derive using Object.create(ConstructorFunction.prototype) instead of just ConstructorFunction .也就是说,你应该得到使用Object.create(ConstructorFunction.prototype)而不是仅仅ConstructorFunction

In JavaScript, even a function is an object and this is why Object.create(...) works when you provide a constructor function.在 JavaScript 中,即使函数也是对象,这就是为什么Object.create(...)在您提供构造函数时起作用的原因。 The resulting object will have the constructor function object as prototype.结果对象将具有构造函数对象作为原型。

Actually you can both use the Object.create(ConstructorFunction.prototype) approach or you can achieve the same goal using new :实际上,您既可以使用Object.create(ConstructorFunction.prototype)方法,也可以使用new实现相同的目标:

Vehicle.prototype = new MovingObject();

The main issue with new approach is that you're creating a new object using a constructor, and maybe you're adding unwanted data and behavior to the prototype: new方法的主要问题是您正在使用构造函数创建一个新对象,并且您可能正在向原型添加不需要的数据和行为:

 function MovingObject() { this.x = 11; } function Vehicle() {} Vehicle.prototype = new MovingObject(); var instance = Object.create(Vehicle.prototype); // What? instance has "x" property!! document.getElementById("result").textContent = instance.x;
 <div id="result"></div>

Update更新

OP said in some comment: OP 在一些评论中说:

Does that mean we cannot establish a true is-a relationship between Car and MovingObject here?这是否意味着我们不能在这里建立真正的汽车和移动对象之间的 is-a 关系? If yes, how can we test it using code?如果是,我们如何使用代码对其进行测试? Meaning, I want to execute some code only if Car is-a Moving object.意思是,只有当 Car 是一个移动对象时,我才想执行一些代码。 How can I achieve the test?我怎样才能达到测试?

Check and execute the following code snippet to be more clear:检查并执行以下代码片段以更清楚:

 function A() {} function B() {} B.prototype = Object.create(A.prototype); function C() {} C.prototype = Object.create(B.prototype); var instanceOfB = Object.create(B.prototype); var instanceOfC = Object.create(C.prototype); var result1 = A.prototype.isPrototypeOf(instanceOfC); var result2 = B.prototype.isPrototypeOf(instanceOfC); var result3 = A.prototype.isPrototypeOf(instanceOfB); document.getElementById("result1").textContent = result1; document.getElementById("result2").textContent = result2; document.getElementById("result3").textContent = result3;
 <h2>A is prototype of instanceOfC?</h2> <div id="result1"></div> <h2>B is prototype of instanceOfC?</h2> <div id="result2"></div> <h2>A is prototype of instanceOfB?</h2> <div id="result3"></div>

Update 2更新 2

As @RobertRossmann has commented out on this answer, same code snippet can be implemented using the instanceof operator, which has the added value of being valid to check if instances are of some prototype providing the constructor function:正如@RobertRossmann 对此答案所评论的那样,可以使用instanceof运算符实现相同的代码片段,该运算符具有附加值,可以检查实例是否属于提供构造函数的某个原型:

 function A() {} function B() {} B.prototype = Object.create(A.prototype); function C() {} C.prototype = Object.create(B.prototype); var instanceOfB = Object.create(B.prototype); var instanceOfC = Object.create(C.prototype); var result1 = instanceOfC instanceof B; var result2 = instanceOfC instanceof C; var result3 = instanceOfB instanceof A; var result4 = instanceOfC instanceof A; document.getElementById("result1").textContent = result1; document.getElementById("result2").textContent = result2; document.getElementById("result3").textContent = result3; document.getElementById("result4").textContent = result4;
 <div id="result1"></div> <div id="result2"></div> <div id="result3"></div> <div id="result4"></div>

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

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