Is it right to think of a Javascript Function Expression that uses the 'new' keyword as 'static'

I'm just trying to understand Javascript a little deeper.

I created a 'class' gameData that I only want ONE of, doesn't need a constructor, or instantiated.

So I created it like so...

var gameData = new function () {

    //May need this later 
    this.init = function () { 
    };

    this.storageAvailable = function () {
        if (typeof (Storage) !== "undefined") {
            return true;
        }
        else {
            return false;
        }
    };
}

Realizing that the 'new' keyword doesn't allow it to be instantiated and makes it available LIKE a static class would be in C#.

Am I thinking of this correctly? As static?

Answers:

Answer

No, it is not static because it still has a constructor property pointing to your "anonymous" function. In your example, you could use

var gameData2 = new (gameData.constructor)();

to reinstantiate a second object, so the "class" (instance actually) is not really "static". You are basically leaking the constructor, and possibly the data that is bound to it. Also, a useless prototype object (gameData.constructor.prototype) does get created and is inserted in the prototype chain of gameData, which is not what you want.

Instead, you might use

  • a single, simple object literal (as in Daff's answer). That means you don't have a constructor, no closure-scoped private variables (you have used none anyway) and no (custom) prototype.
  • the (revealing) module pattern (as in jAndy's answer). There you'd have an IIFE to create closure-scoped variables, and can return any kind of object.
  • an actual constructor ("class") that can be instantiated later (when needed), and yields the same singleton object always.

This is what the singleton pattern would look like:

function GameData() {
    if (this.constructor.singleton)
        return this.constructor.singleton;
    else
        this.constructor.singleton = this;

    // init:
    // * private vars
    // * public properties
    // ...
}
GameData.prototype.storageAvailable = function () {
    if (typeof (Storage) !== "undefined") {
        return true;
    }
    else {
        return false;
    }
};

var gameData = new GameData();
var gameData2 = new GameData();
gameData === gameData2 === GameData.singleton; // true

Yet, the prototype is quite useless because you have only one instance of GameData. It would only get interesting with inheritance.

Answer

There is no Class in ECMAscript, there is only Object.

When new is used to invoke a function, we call it a constructor function. This function somewhat auto returns a new object once it finished. Any data that is stored within that object using this (which references that newly created object) is returned as property of that object. Beside that, new sets a property called constructor to exactly this function.

In your case, you don't even really require the usage of new, you could easily re-write your code as follows:

var gameData = (function () {
    var public = { },
        private = { }; // any private data can get stored here

    //May need this later 
    public.init = function () { 
    };

    public.storageAvailable = function () {
        if (typeof (Storage) !== "undefined") {
            return true;
        }
        else {
            return false;
        }
    };

    return public;
}());

This is called the factory pattern, singleton pattern, module pattern, and there might be some other names.

Answer

I think what you are looking for is just a simple JavaScript object:

var gameData = {
    //May need this later 
    init : function () { 
    },

    storageAvailable : function () {
        if (typeof (Storage) !== "undefined") {
            return true;
        }
        else {
            return false;
        }
    }
}

If you want to use private variables create a revealing module pattern style wrapper. This is basically what jAndy suggested:

var gameData = (function() {
    var private = 'private variable';

    return {
        //May need this later 
        init : function () { 
        },

        storageAvailable : function () {
            if (typeof (Storage) !== "undefined") {
                return true;
            } else {
                return false;
            }
        }
    }
})();

Tags

Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us

©2020 All rights reserved.