Max*_*kyi 11 javascript inheritance
我画了下面的图片,演示了如何继承对象(函数构造函数标记为蓝色,从这些构造函数创建的对象标记为绿色):
以下是创建此类层次结构的代码:
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();
Run Code Online (Sandbox Code Playgroud)
现在我想检查是否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()
Run Code Online (Sandbox Code Playgroud)
所以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()
Run Code Online (Sandbox Code Playgroud)
因此,使用此检查逻辑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));Run Code Online (Sandbox Code Playgroud)
如您所见,在配置时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));Run Code Online (Sandbox Code Playgroud)
现在结果是每个人都期望的结果.
编辑
我重新绘制了你的图片,并绘制了另一个图片,它说明了对象的真实基于你的文本示例,这与我的第二个代码相同.
原文:我突出了表达式中的引用Rect.prototype === new Circle().__proto__.__proto__:
第二个:
PS
今天在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));Run Code Online (Sandbox Code Playgroud)