Shapes using operator new

Some JavaScript shape objects implemented with operator new, with unit tests, of course

by Ray Toal

HTML

<script src="https://code.jquery.com/qunit/qunit-git.js"></script>
<link rel="stylesheet" href="https://code.jquery.com/qunit/qunit-git.css">
<div id="qunit"></div>
<div id="qunit-fixture"></div>

JavaScript

/*
 * A circle datatype.
 *
 * Synopsis:
 * let c = new Circle(10);
 * c.radius ==> 10
 * c.area() ==> 314.1592653589793
 * c.perimeter() ==> 62.83185307179586
 */
let Circle = function (r) {
  this.radius = r;
};

Circle.prototype.area = function () {
  return Math.PI * this.radius * this.radius;
};

Circle.prototype.perimeter = function () {
  return 2 * Math.PI * this.radius;
};

/*
 * A rectangle datatype.
 *
 * Synopsis:
 * let r = new Rectangle(5, 8);
 * r.length ==> 5
 * r.width ==> 8
 * r.area() ==> 40
 * r.perimeter() ==> 26
 */
let Rectangle = function (w, h) {
  this.width = w;
  this.height = h;
};

Rectangle.prototype.area = function () {
  return this.width * this.height;
};

Rectangle.prototype.perimeter = function () {
  return 2 * (this.width + this.height);
};

/*
 * A polygon datatype.
 *
 * Synopsis:
 * let p = new Polygon([[0,0], [5,12], [5,0]]);
 * p.length ==> 3
 * p.points ==> [[0,0], [5,12], [5,0]]
 * p.area() ==> 30
 * p.perimeter() ==> 30
 *
 * PRECONDITION: The points must be entered in clockwise order and
 * the polygon should not be self-intersecting, otherwise the area()
 * function will almost certainly fail.
 *
 * LIMITATIONS: The constructor simply captures and stores the array
 * argument passed to it, so modifying the argument outside of the
 * polygon operations will have the side-effect of changing the polygon
 * itself.
 */
let Polygon = function (points) {
  this.points = points;
};

Polygon.prototype.area = function () {
  let sum = 0;
  for (let i = 0, n = this.points.length, j = n - 1; i < n; j = i, i += 1) {
    let p = this.points[j], q = this.points[i];
    sum += (p[0] + q[0]) * (p[1] - q[1]);
  }
  return sum / 2;
};

Polygon.prototype.perimeter = function () {
  let distance = (p, q) => {
    let dx = p[0] - q[0], dy = p[1] - q[1];
    return Math.sqrt(dx * dx + dy * dy);
  };
  let length = 0;
  for (var i = 0, n = this.points.length, j = n - 1; i < n; j = i, i += 1) {
    length += distance(this.points[j],...