JavaScript:图解继承、__proto__和prototype的概念

4
我有以下代码:
function Shape(x, y) {
    this.x = x;
    this.y = y;
}

Shape.prototype.describeLocation = function() {
    return 'I am located at ' + this.x + ', ' + this.y;
};

var myShape = new Shape(1, 2);

function Circle(x, y, radius) {
    Shape.call(this, x, y);  // call parent constructor
    this.radius = radius;
}

var myFirstCircle = new Circle(3, 4, 10);

Circle.prototype = Object.create(Shape.prototype);

Circle.prototype.calculateArea = function() {
    return 'My area is ' + (Math.PI * this.radius * this.radius);
};

var mySecondCircle = new Circle(3, 4, 10);

我想要一个可视化的解释:

  • Circle.prototype = Object.create(Shape.prototype); 引起的变化
  • 对象之间 __proto__prototype 的连接关系
  • mySecondCircle 如何从 Shape 继承了 describeLocation() 方法
  • 为什么 mySecondCirclecalculateArea() 方法,但是 myFirstCircle 没有:

> myFirstCircle.calculateArea()
Uncaught TypeError: undefined is not a function

> mySecondCircle.calculateArea()
"My area is 314.1592653589793"

* 在尝试理解JavaScript继承问题时,一张图确实胜过千言万语,我发现这些问题中的图表非常有帮助:worth a thousand words, 1, 2, 3, 4


哦,那是一个很好的图表链接收藏 :-) - Bergi
2个回答

15

图示 查看完整版 — 图片网页

Circle.prototype(原始) 是在 function Circle(...) {...} 的定义过程中被创建的副作用。

Circle.prototype (重新定义)Circle.prototype = Object.create(Shape.prototype); 创建。


我还制作了一个动画版本以展示对象创建的顺序:

动画图示 查看完整版 — 图片网页


你用什么软件画的? - Kutsan Kaplan
我知道上面的内容已经变灰,但是原始的Circle.prototype仍然作为myFirstCircle实例的原型处于活动状态,对吗?(不确定为什么我在问这个问题,我猜想这是正确的,因为我在Chrome中测试过了 :) ) - armyofda12mnkeys

0
为什么mySecondCircle有calculateArea()方法而myFirstCircle没有呢?
通过重新分配Circle.prototype,您正在取消引用已创建的实例使用的原型。以下代码演示了这一点:
var org = {name:"org"}
var copy1 = org;//copy1===org
org={name:"changed"};org!==copy1
var copy2 = org;//copy2===org
org.name="again";//copy2.name === "again"

当我们通过将一个完全不同的对象分配给org(取消引用它)来更改组织名称时,copy1和org不再指向同一对象。

当我们设置org的名称属性(改变org)时,copy2和org仍然指向同一对象。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接