Правильно ли думать о выражении функции Javascript, которое использует "новое" ключевое слово как "статическое",

Я просто пытаюсь понять Javascript немного глубже.

Я создал "класс" gameData, для которого я хочу только ОДИН из, не нужен конструктор или экземпляр.

Итак, я создал его так...

var gameData = new function () {

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

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

Понимая, что ключевое слово 'new' не позволяет создавать экземпляр и делает его доступным, КАК статический класс будет в С#.

Я думаю об этом правильно? Как статический?

Ответ 1

Нет, он не является статичным, поскольку он все еще имеет свойство constructor, указывающее на вашу "анонимную" функцию. В вашем примере вы можете использовать

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

чтобы восстановить второй объект, поэтому "класс" (фактически экземпляр) не является "статическим". Вы в основном просачиваете конструктор и, возможно, данные, привязанные к нему. Кроме того, создается бесполезный объект-прототип (gameData.constructor.prototype) и вставляется в цепочку прототипов gameData, которая не является тем, что вы хотите.

Вместо этого вы можете использовать

  • единственный, простой объектный литерал (как в Daff answer). Это означает, что у вас нет конструктора, нет закрытых переменных с закрытой областью (вы все равно не использовали их) и нет (настраиваемый) прототип.
  • (раскрывающий) шаблон модуля (как в jAndy answer). Там у вас будет IIFE, чтобы создавать переменные с закрытой областью и может возвращать любые объекты.
  • фактический конструктор ( "класс" ), который может быть создан позже (когда это необходимо) и всегда дает один и тот же одноэлементный объект.

Вот как выглядит одноэлементный шаблон:

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

Однако прототип совершенно бесполезен, потому что у вас есть только один экземпляр gameData. Это будет интересно только с наследованием.

Ответ 2

В ECMAscript нет класса, есть только объект.

Когда new используется для вызова функции, мы называем ее конструкторной функцией. Эта функция несколько автоматически возвращает новый объект после его завершения. Любые данные, которые хранятся в этом объекте с использованием this (который ссылается на вновь созданный объект), возвращаются как свойство этого объекта. Кроме того, new задает свойство, называемое конструктором, точно такой функции.

В вашем случае вы даже не требуете использования new, вы можете легко переписать код следующим образом:

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;
}());

Это называется шаблоном factory, шаблоном singleton, шаблоном модуля, и могут быть и другие имена.

Ответ 3

Я думаю, что вы ищете просто простой объект JavaScript:

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

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

Если вы хотите использовать частные переменные, создайте оболочку стиля шаблона показательного модуля. Это в основном то, что предложил Джанди:

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;
            }
        }
    }
})();