我画了下图,展示了对象是如何继承的(函数构造函数被标记为蓝色,从那些构造函数创建的对象被标记为绿色):
这是创建这种层次结构的代码:
function Figure() {}
function Rect() {}
Rect.prototype = new Figure();
function Square() {}
Square.prototype = new Rect();
function Ellipse() {}
Ellipse.prototype = new Figure();
function Circle() {}
Circle.prototype = new Ellipse();
现在,我想检查是否new Square()
继承自Rect
,因此这是我期望JavaScript引擎检查的方式:
var s = new Square();
s instanceof Rect // ?
s.__proto__ === Rect.prototype // false
new Rect() new Figure()
s.__proto__.__proto__ === Rect.prototype // true
new Figure() new Figure()
所以s instanceof Rect
应该退货true
。这是预料之中的,实际上是我运行代码后返回的结果。但是然后我想检查是否new Circle()
继承自Rect
,所以我遵循相同的逻辑:
var c = new Circle();
c instanceof Rect // ?
c.__proto__ === Rect.prototype // false
new Ellipse() new Figure()
c.__proto__.__proto__ === Rect.prototype // true
new Figure() new Figure()
因此,使用此检查逻辑c instanceof Rect
应返回true
,但如果我实际运行代码,则c instanceof Rect
返回false。我是否误解了instanceof
操作员的机制?
您的逻辑是正确的,但最初的假设有些错误。可以使用原型来模拟基于常规类的继承。
为了重现您绘制的结构,我创建了以下代码:
function Figure() {}
function Rect() {}
function Square() {}
function Ellipse() {}
function Circle() {}
Ellipse.prototype = Rect.prototype = new Figure();
Square.prototype = new Rect();
Circle.prototype = new Ellipse();
console.log("is Figure: " + (new Circle() instanceof Figure));
console.log("is Ellipse: " + (new Circle() instanceof Ellipse));
console.log("is Rect: " + (new Circle() instanceof Rect));
如您所见,new Circle() instanceof Rect
按置备返回true。问题在于,通过将Ellipse.prototype
和设置Rect.prototype
为相同的对象,它们基本上变成了相同的类型(具有多个构造函数)。
那么如何解决呢?Figure
为原型创建不同的实例,如下所示:
function Figure() {}
function Rect() {}
function Square() {}
function Ellipse() {}
function Circle() {}
Ellipse.prototype = new Figure();
Rect.prototype = new Figure();
Square.prototype = new Rect();
Circle.prototype = new Ellipse();
console.log("is Figure: " + (new Circle() instanceof Figure));
console.log("is Ellipse: " + (new Circle() instanceof Ellipse));
console.log("is Rect: " + (new Circle() instanceof Rect));
现在的结果是每个人都期望的。
编辑
我重新绘制了您的图片,并绘制了另一张图片,该图片根据您的文本示例说明了这些对象实际上是如何创建的,这与第二个代码相同。
原始的一个:我突出显示了表达式中的引用Rect.prototype === new Circle().__proto__.__proto__
:
第二个:
聚苯乙烯
在2016年的今天,不是Circle.prototype = new Ellipse()
实现继承的方法,而是使用标准的类继承:
class Figure {}
class Rect extends Figure {}
class Square extends Rect {}
class Ellipse extends Figure {}
class Circle extends Ellipse {}
console.log("new Circle is Figure: " + (new Circle() instanceof Figure));
console.log("new Circle is Rect: " + (new Circle() instanceof Rect));
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句