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

3

29

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?

Wonderland answered 2/5, 2012 at 1:24 Comment(4)
If you only need a single instance of an object, why use a constructor at all?Waylay
Not sure I understand your question. I created it this way as opposed to a basic object literal so I could have private and public properties and methods.Wonderland
Related : #17008586Trauner
see also new function() with lower case “f” in JavaScriptYnes
Y
30

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.

Ynes answered 2/5, 2012 at 1:31 Comment(0)
E
16

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.

Ethno answered 2/5, 2012 at 1:28 Comment(7)
you should call it a "self-invoked anonymous factory".Ynes
Thanks! This looks very interesting.. and something MORE for me to try and digest! :)Wonderland
@toddv: a very good advice and recommendation is "JavaScript: The good parts" by Douglas Crockford to get into ECMAscript inheritance, Objects+prototypes.Ethno
I think singleton is a quite different pattern, because singletons are still instances of a "class".Ynes
This is not the singleton pattern. Also, ES -> ES5.Trauner
There is no Class in ECMAscript. Actually, with ES6, now there is.Pagination
Isn't that just a cleaner syntax for the same thing? - "Classes are in fact functions" developer.mozilla.org/en/docs/Web/JavaScript/Reference/ClassesMali
F
5

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;
            }
        }
    }
})();
Flagging answered 2/5, 2012 at 1:28 Comment(2)
I didn't go this route because I wanted to have public and private methods and constructors...and that cannot be accomplished using object literals...correct?Wonderland
I updated my answer for private variables. I don't see why you would need a constructor for a static class though?Flagging

© 2022 - 2024 — McMap. All rights reserved.