2

I know I can create a class with this code:

class Polygon {
    constructor(height, width) {
      this.height = height;
      this.width = width;
    }
}

However, I would like this Polygon class to reside within a namespace called Model so that I can instantiate Polygon objects like this:

var myNewPolygon = new Model.Polygon(10, 50);

Is this possible?

I have tried the following:

var Model = Model || {};
class Model.Polygon {
    constructor() {
      this.height = height;
      this.width = width;
    }
}
var myNewPolygon = new Model.Polygon(10, 50);

But this results in Uncaught SyntaxError: Unexpected token . on line 2.

I have also tried:

var Model = Model || {};
class Polygon {
    constructor(height, width) {
      this.height = height || 0;
      this.width = width || 0;
    }
}
Model.Polygon = new Polygon();
var myNewPolygon = new Model.Polygon(10, 50);

But this results in Uncaught TypeError: Model.Polygon is not a constructor on line 9.

Leo Galleguillos
  • 2,429
  • 3
  • 25
  • 43

1 Answers1

3

Almost there.

var Model = Model || {};
Model.Polygon = class {
    constructor(height, width) {
      this.height = height || 0;
      this.width = width || 0;
    }
}

var myNewPolygon = new Model.Polygon(10, 50);

Classes can be unnamed (aka "anonymous") just like a function, and just like a function, unnamed classes can be assigned to variables, as above with Model.Polygon = class { ... }

If you need the class to reference itself within the body of the class, then you can give it a name. Note that the class name will not be available outside the body of the class.

var Model = Model || {};
Model.Polygon = class Polygon {
    constructor(height, width) {
      this.height = height || 0;
      this.width = width || 0;
    }

    equals(other){
      // Returns true if other is also an instance of Polygon
      // and height and width are the same.
      return ( other instanceof Polygon )     &&
             ( other.height === this.height ) &&
             ( other.width === this.width );
    }
}

var myNewPolygon1 = new Model.Polygon(10, 50);
var myNewPolygon2 = new Model.Polygon(10, 50);
myNewPolygon1.equals( myNewPolygon2 ); // returns true
myNewPolygon1.equals({ height: 10, width: 50 }); // returns false

var myNewPolygon3 = new Polygon(10, 50); // Uncaught ReferenceError: Polygon is not defined
JDB
  • 25,172
  • 5
  • 72
  • 123
  • Looks like I can use an anonymous class as in your first example. Then, if I need to reference the class itself, I can use the full namespaced path. `(this instanceof Model.Polygon)` will return true in the first example, even though Model.Polygon points to the anonymous class. – Leo Galleguillos Jul 06 '16 at 19:27
  • 1
    Yup. But a minifier wouldn't be able to minify Model.Polygon (assuming you export the Model namespace), but could minify Polygon (since the name is locally scoped). Depending on how often you reference that name (and whether or not you minify the file), it could make a few bytes worth of difference in download time and overall web page responsiveness. – JDB Jul 06 '16 at 19:31
  • (Note: Apparently uglifier/minifier support for ECMA 6 is still [not universal](http://stackoverflow.com/q/36482076/211627)) – JDB Jul 06 '16 at 19:37