4

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.

Community
  • 1
  • 1
TachyonVortex
  • 8,242
  • 3
  • 48
  • 63

2 Answers2

15

Diagram 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:

Animated diagram Full-size — image, page.

TachyonVortex
  • 8,242
  • 3
  • 48
  • 63
  • Which software did you use to draw? – Kutsan Kaplan Dec 11 '16 at 03:04
  • I know its greyed out above, but the original Circle.prototype is still active as the prototype on myFirstCircle instance, correct? (not sure why I'm asking, I guess I know this is true since I tested it in Chrome :) ) – armyofda12mnkeys Mar 15 '22 at 02:28
0

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.

HMR
  • 37,593
  • 24
  • 91
  • 160