【问题标题】:Singleton design pattern in JavascriptJavascript 中的单例设计模式
【发布时间】:2016-06-30 05:28:21
【问题描述】:

我正在关注此链接https://addyosmani.com/resources/essentialjsdesignpatterns/book/ 以了解 Javascript 中的设计模式 我了解了构造函数模式、模块模式和模块显示模式,现在在单例模式中我有两个疑问:

1) 我知道 c++ 并且我现在正在学习 JavaScript,所以我理解单例模式只允许您使用该类的一个实例,但在本书中提到“在 JavaScript 中,单例作为共享资源命名空间,将实现代码与全局命名空间,以便为函数提供单点访问。”什么意思???

2)

var mySingleton = (function () {

// Instance stores a reference to the Singleton
var instance;

function init() {

// Singleton

// Private methods and variables
function privateMethod(){
    console.log( "I am private" );
}

var privateVariable = "Im also private";

var privateRandomNumber = Math.random();

return {

  // Public methods and variables
  publicMethod: function () {
    console.log( "The public can see me!" );
  },

  publicProperty: "I am also public",

  getRandomNumber: function() {
    return privateRandomNumber;
  }

};

};

return {

// Get the Singleton instance if one exists
// or create one if it doesn't
getInstance: function () {

  if ( !instance ) {
    instance = init();
  }

  return instance;
}

};

})();

var singleA = mySingleton.getInstance();
var singleB = mySingleton.getInstance();

我怀疑当我们调用 mySingleton.getInstance();不会再次成为未定义的值“实例”,因为它是一个局部变量,每次我们调用 getInstance 方法时,它都应该将实例值设置为未定义,因此 如果 ( !instance )
应该总是通过并给出一个新的实例,但我不明白它是如何在这里工作的。请解释一下。

【问题讨论】:

  • 不,var instance 定义在“外部”范围内。 (不在getInstance函数范围内)
  • 我的建议是查看 Javascript 中的闭包。
  • 感谢第 2 点现在很清楚......但是第 1 点呢?请解释...
  • @user3651606 这本书是否暗示在 javascript 中单例的使用方式与其他语言不同?该文本排序只是定义了单例是什么。

标签: javascript design-patterns


【解决方案1】:

var mySingleton 是一个 IIFE 函数,它会返回一个对象(或在模块中显示模式术语,公开 getInstance 的属性)

每次mySingleton在代码中被引用,它里面的内容每次都会执行。因此重置实例变量。注意,init 方法还返回一个具有 3 个属性的对象 ,表明这些属性也是可公开的(可以公开,甚至可以通过在公共函数中处理私有变量来公开它们。漂亮很多 C++/Java 概念)

最后,我们使用这个 init() 并将其标记为 getInstance

因此,当我这样做时 var singleA = mySingleton.getInstance(); var singleB = mySingleton.getInstance();

我可以访问(选择性地)“公开”属性 singleA.publicMethod()

流程:singleA [指] getInstance() [通过] mySingleton [和] getInstance() strong> [指] init() [公开] publicMethodpublicPropertygetRandomNumber [间接给出您访问] privateRandomNumber

疑问 #1 作为共享资源命名空间并隐藏代码实现。 当您位于 init 上方 1 级的命名空间中时,它会全局共享 init 方法的私有属性和方法。

私有方法被隐藏而不暴露。

疑问 #2 每次引用 mySingleton 时,都会重新声明实例。

希望对你有帮助

【讨论】:

    【解决方案2】:

    1) 这意味着现在只能从全局命名空间访问变量 var mySingleton。它公开了单个公共方法getInstance,该方法返回一个且只有一个类的实例(负责管理对此实例的私有引用的代码对外部范围隐藏)。

    2) 不,var instance 定义在“外部”范围内。 (不在getInstance函数范围内)

    【讨论】:

      【解决方案3】:

      在 javascript 中 Object 是一个引用数据类型,这意味着这里返回的实例是相同的。

      var singleA = mySingleton.getInstance();
      var singleB = mySingleton.getInstance();
      
      singleA === singleB // > true
      

      我们能够在 mySingleton 的 getInstance 函数中访问实例变量是由于闭包的

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-10-12
        • 1970-01-01
        • 2010-11-03
        • 1970-01-01
        相关资源
        最近更新 更多