考虑使用'new'关键字作为'static'的Javascript函数表达式是否正确

Tod*_*nce 25 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;
        }
    };
}
Run Code Online (Sandbox Code Playgroud)

意识到'new'关键字不允许它实例化并使其可用LIKE静态类将在C#中.

我是否正确地想到了这一点?静电?

Ber*_*rgi 27

不,它不是静态的,因为它仍然具有constructor指向您的"匿名"功能的属性.在您的示例中,您可以使用

var gameData2 = new (gameData.constructor)();
Run Code Online (Sandbox Code Playgroud)

重新实现第二个对象,所以"类"(实际上是实例)并不是真正的"静态".您基本上是泄漏构造函数,可能还有绑定到它的数据.此外,一个无用的原型对象(gameData.constructor.prototype)确实被创建并插入原型链中gameData,这不是你想要的.

相反,你可以使用

  • 单个简单的对象文字(如Daff的答案).这意味着你没有构造函数,没有封闭范围的私有变量(你无论如何都使用过)和没有(自定义)原型.
  • (揭示)模块模式(如jAndy的回答).在那里你有一个IIFE来创建闭包范围的变量,并且可以返回任何类型的对象.
  • 一个实际的构造函数("class"),可以在以后实例化(需要时),并始终生成相同的单例对象.

这就是单例模式的样子:

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
Run Code Online (Sandbox Code Playgroud)

然而,原型是没用的,因为你只有一个实例GameData.它只会对继承感兴趣.


jAn*_*ndy 14

ECMAscript中没有,只有Object.

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;
}());
Run Code Online (Sandbox Code Playgroud)

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

  • @toddv:一个非常好的建议和推荐是Douglas Crockford的"JavaScript:好的部分",以进入ECMAscript继承,Objects + prototypes. (2认同)
  • "ECMAscript中没有类." 实际上,有了ES6,现在有了. (2认同)
  • 对于同样的事情,这不仅仅是一个更清晰的语法吗? - "类实际上是函数"https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Classes (2认同)

Daf*_*aff 6

我认为你要找的只是一个简单的JavaScript对象:

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

    storageAvailable : function () {
        if (typeof (Storage) !== "undefined") {
            return true;
        }
        else {
            return false;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

如果要使用私有变量,请创建一个显示模块模式样式包装器.这基本上是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;
            }
        }
    }
})();
Run Code Online (Sandbox Code Playgroud)

  • 我更新了私有变量的答案.我不明白为什么你需要静态类的构造函数呢? (2认同)