具有构造函数的语义JavaScript单例

alt*_*alt 3 javascript singleton

所以我希望有一个名为" client我将用JavaScript编写的视频游戏的基础"的课程.

client 应该是一个只能有一个实例的类,但是它的第一个创建应该由我自己在特定事件中设置,例如当用户单击"开始"按钮时.

我让自己成为一个单独的类,我开始卸载它只是为了测试:

// Singleton class for the client
var client = (function() {

  // Public methods
  var _this = {
    construct: function() {
      delete _this.construct;
      _this.director = new lime.Director(document.body, window.innerWidth, window.innerHeight); // Setup the rendering engine
    }
  }
  return _this;
})();

// Fire when dependencies are loaded
window.onload = client.construct;
Run Code Online (Sandbox Code Playgroud)

问题:

但我打算将其作为一个开源项目,并且在最后一行client.construct似乎是一个非常不寻常的惯例.我如何编写我的单例类,以便它将被构造,new Client并且永远不能再构造?

Mar*_*ery 7

首先:你确定你真的想这样做吗?对于大多数简单的情况,你可能最好不要打扰prototype或者根本不使用new关键字,而只是用你想要的属性和方法编写一个对象文字 - 或者创建一个具有一次性函数的对象,如果稍微多一点需要复杂的构造逻辑.简单是好的.

我想有几种情况你可能想在JavaScript中创建一个"传统的"单例,比如延迟实例化,或者如果你使用涉及单例类原型的经典继承.

在这种情况下,您可能希望尝试基于bfavaretto的方法,其中类的用户期望通过调用Client.getSingletonInstance()而不是获取Client对象new Client(),并且newgetSingletonInstance()方法内部发生Client的实例化.

var Client = (function() {
    // Our "private" instance
    var instance;

    // The constructor
    function Client() {

        // If it's being called again, throw an error
        if (typeof instance != "undefined") {
            throw new Error("Client can only be instantiated once.");
        }

        // initialize here

        // Keep a closured reference to the instance
        instance = this;
    }

    // Add public methods to Client.prototype
    Client.prototype.myPublic = function() {

    }

    Client.getSingletonInstance = function() {
        if (typeof instance == "undefined") {
            return new this();
        }
        else {
            return instance;
        }
    }

    // Return the constructor
    return Client;
})();


var c1 = Client.getSingletonInstance();
var c2 = Client.getSingletonInstance();

console.log(c1 == c2); // true
Run Code Online (Sandbox Code Playgroud)

我更喜欢这种方式,因为在我看来,拥有类调用的用户new但实际上没有获得新对象会产生误导.

http://jsfiddle.net/hBvSZ/3/