JavaScript: Diagram to explain inheritance, __proto__ and prototype

梦想的初衷 提交于 2019-12-30 01:39:06

问题


I have the following code:

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

I'd like a visual* explanation of:

  • the changes caused by Circle.prototype = Object.create(Shape.prototype);
  • the __proto__ and prototype connections between the objects
  • how mySecondCircle inherits the describeLocation() method from Shape
  • why the calculateArea() method exists for mySecondCircle but not for myFirstCircle:

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

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

* When trying to understand JavaScript issues regarding inheritance, a diagram really is worth a thousand words, and I've found the diagrams in these questions very helpful: 1, 2, 3, 4.


回答1:


Full-size — image, page.

Circle.prototype (original) is created as a side-effect of function Circle(...) {...}

Circle.prototype (redefined) is created by Circle.prototype = Object.create(Shape.prototype);


I also made this animated version to show the order in which the objects are created:

Full-size — image, page.


回答2:


why the calculateArea() method exists for mySecondCircle but not for myFirstCircle:

By re assigning the Circle.prototype you are de referencing the proto used by instances already created. Following code demonstrates:

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"

When we change org name by assigning a completely different object to org (de referencing it) copy1 and org no longer point to the same object.

When we set the name property of org (mutate org) copy2 and org still point to the same object.



来源:https://stackoverflow.com/questions/29155986/javascript-diagram-to-explain-inheritance-proto-and-prototype

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!