Search code examples
javascriptstaticecmascript-6ecmascript-5

How to declare static, constant arrays for a javascript class inside anonymous function?


I'm working on a JS script to render a guitar fretboard. I need to declare two static vars in my class. One object to map note names like "C#" onto their integer MIDI note the other an array of objects providing details for each midi mote. It looks like I have to declare these after the class/function itself but I want to be sure I can refer to them in the constructor function.

Complicating matters is that I want to namespace my code inside an anonymous function to prevent name collisions--I understand these are best practices.

I've been puttering around with some code and have something like this, but I don't think the stuff at the end is going to work.

(function(){

    // object to encapsulate this module
    var MyClass = function() {
        this.foo = "foo";
        this.bar = "bar";
    };

    MyClass.nameToMidiNumber = {"C0":0,"C#0":1,"Db0":1,"D0":2,"D#0":3,"Eb0":3}; // and so on

    MyClass.midiData = [{"octave":0,"utf8_name":"C","ascii_name":"C","frequency":8.1757989156},{"octave":0,"utf8_name":"C♯\/D♭","ascii_name":"C#\/Db","frequency":8.661957218}]; // etc



    if(typeof window!="undefined"){
        window.MYNAMESPACE || (window.MYNAMESPACE = {});
        if(window.MYNAMESPACE.MyClass){
            for(var prop in MyClass){
                window.MYNAMESPACE.MyClass[prop]=MyClass[prop]
            }
        }else{
            window.MYNAMESPACE.MyClass=MyClass
        }
    } else {
        throw "'window' not defined. Unable to attach MyClass.";
    }
})();

Am I doing this right? Ideally, after including this script with an HTML tag:

<script type="text/javascript" src="myscript.js"></script>

then I could just instantiate the object like so:

var gtr = new MYNAMESPACE.MyClass(prm1, prm2, prm3);

I'm also aware that a transition is currently underway to ES6 which has the class and static keywords. Should I be using that instead?


Solution

  • Feel free to use ES6 and classes if you don't have to support IE9. Otherwise, you'll have to use babel to transpile from ES6 to ES5 -- "nonsense," as you so eloquently put it.

    Window should normally be available in a browser window at any time you're running javascript, so I don't think you have to check whether the window is defined or not. Some info here:

    Is window.document ever null or undefined?

    I think the code you use to iterate over keys in an object is OK. ES6 has much cleaner ways of doing similar things, and it's worth taking a look.

    Finally, yes, you can use ES6 functionality for classes, or the NEW keyword works, too. One is classical, and one is prototypal, and purists might prefer sticking with the latter despite being older.