Javascript 使用';新';关键字as';静态';

Javascript 使用';新';关键字as';静态';,javascript,Javascript,我只是想更深入地理解Javascript 我创建了一个“类”gameData,我只想要其中一个,不需要构造函数,也不需要实例化 所以我就这样创造了它 var gameData = new function () { //May need this later this.init = function () { }; this.storageAvailable = function () { if (typeof (Storage) !==

我只是想更深入地理解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”关键字不允许对其进行实例化,并使其可用,就像C#中的静态类一样

我想得对吗?作为静态?

ECMAscript中没有类,只有对象

当使用
new
调用函数时,我们称之为构造函数。此函数在完成后自动返回一个新对象。使用
this
(引用新创建的对象)存储在该对象中的任何数据都将作为该对象的属性返回。除此之外,
new
为该函数设置一个名为constructor的属性

在您的情况下,甚至不需要使用
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;
}());

这称为工厂模式、单例模式、模块模式,可能还有其他一些名称

我认为您需要的只是一个简单的JavaScript对象:

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

    storageAvailable : function () {
        if (typeof (Storage) !== "undefined") {
            return true;
        }
        else {
            return false;
        }
    }
}
如果要使用私有变量,请创建一个显示模块模式样式的包装器。这基本上是jAndy建议的:

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

不,它不是静态的,因为它仍然有一个
构造函数
属性指向“匿名”函数。在您的示例中,您可以使用

var gameData2 = new (gameData.constructor)();
重新实例化第二个对象,使“类”(实际上是实例)不是真正的“静态”。基本上,您正在泄漏构造函数,可能还有绑定到它的数据。另外,会创建一个无用的原型对象(
gameData.constructor.prototype
),并将其插入到
gameData
的原型链中,这不是您想要的

相反,您可以使用

  • 单个简单的对象文字(如中)。这意味着您没有构造函数,没有闭包范围的私有变量(您无论如何都没有使用),也没有(自定义)原型
  • (显示)模块模式(如中所示)。在这里,您可以创建闭包范围的变量,并可以返回任何类型的对象
  • 一个实际的构造函数(“类”),可以稍后(在需要时)实例化,并始终生成相同的单例对象
这就是singleton模式的外观:

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
实例。只有继承才会让人感兴趣。

如果你只需要一个对象的单个实例,为什么还要使用构造函数呢?我不太明白你的问题。我创建它的方式与基本对象文字不同,这样我就可以拥有私有和公共属性和方法。相关:请参阅,我之所以没有这样做,是因为我想拥有公有和私有方法以及构造函数……而这是使用对象文字无法实现的……正确吗?我更新了私有变量的答案。我不明白为什么静态类需要构造函数?应该称之为“自调用匿名工厂”。谢谢!这看起来很有趣。。还有一些东西让我试着去消化!:)@toddv:Douglas Crockford的“JavaScript:The good parts”是一个非常好的建议和建议,用于进入ECMAscript继承、对象+原型。
ECMAscript中没有类。事实上,对于ES6,现在有了。这难道不是一个更简洁的语法吗“类实际上是函数”