gpt4 book ai didi

javascript - 了解原型(prototype)继承

转载 作者:可可西里 更新时间:2023-11-01 02:20:54 24 4
gpt4 key购买 nike

我画了下图来演示对象是如何继承的(函数构造函数标记为蓝色,从这些构造函数创建的对象标记为绿色):

enter image description here

下面是创建这种层次结构的代码:

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 运算符的机制?

最佳答案

您的逻辑是对的,但最初的假设有点错误。可以使用原型(prototype)模拟常规的基于类的继承。

为了重现您为我们绘制的结构,我创建了以下代码:

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.prototypeRect.prototype 设置为同一个对象,它们基本上变成了相同的类型(具有多个构造函数)。

那么如何解决呢?为原型(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__ 中的引用:

enter image description here

第二个:

enter image description here

附言

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

关于javascript - 了解原型(prototype)继承,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38084255/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com