Wilt
Wilt

Reputation: 44383

Extend javascript classes and wrap them in a container object

In ES6 you can have your custom classes extend javascript built-in objects. Like this you can make Array, Number, String, Date objects with custom methods.

I Was experimenting with this and tried to wrap my objects inside a container object called My, simply following the example here from MDN (Mozilla Developer Network). But when I define my custom Date class inside the object like this:

var My = {};

class My.Date extends Date {
  constructor() {
    super();
  }

  getFormattedDate() {
    var months = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'];
    return this.getDate() + "-" + months[this.getMonth()] + "-" + this.getFullYear();
  }
}

I get the following SyntaxError:

Uncaught SyntaxError: Unexpected token .

Here is a fiddle that demonstrates this.

I bet there is some way to work around this but I am not sure how to do that...

Upvotes: 0

Views: 665

Answers (2)

Wilt
Wilt

Reputation: 44383

A workaround would be wrapping the logic in a function so that the new class is declared in the functions local scope and then adding it to the global My container inside the function.
Like this you can use the customized objects (extended primitives) without messing with the global objects and they will still look similar (For example the class name is Date when printed in console).

var My = {};

function init(){

    class Date extends window.Date {
        constructor() {
            super();
        }

        getFormattedDate() {
            var months = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'];
            return this.getDate() + "-" + months[this.getMonth()] + "-" + this.getFullYear();
        }
    }

    My.Date = Date;

}

init();

Date === window.Date; // true
My.Date === window.Date; // false
My.Date.name // Date -> class name
new My.Date().getFormattedDate(); // 2-Jun-2016

Another solution from this answer here:

var My = {};

My.Date = class extends Date {
    constructor() {
        super();
    }

    getFormattedDate() {
        var months = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'];
        return this.getDate() + "-" + months[this.getMonth()] + "-" + this.getFullYear();
    }
}

Upvotes: 0

Dieterg
Dieterg

Reputation: 16368

It's not allowed to use .'s in your classname. But it is possible to add the class instance to your namespace.

var My = {};

class MyDate extends Date {
  constructor() {
    super();
  }

  getFormattedDate() {
    var months = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'];
    return this.getDate() + "-" + months[this.getMonth()] + "-" + this.getFullYear();
  }
}

My.Date = MyDate;

Or directly

var My = {};

My.Date = class MyDate extends Date {
  constructor() {
    super();
  }

  getFormattedDate() {
    var months = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'];
    return this.getDate() + "-" + months[this.getMonth()] + "-" + this.getFullYear();
  }
}

Upvotes: 2

Related Questions