原文:https://segmentfault.com/a/1190000012842251

定义

确保一个类仅有一个实例,并提供一个访问它的全局访问点。

单例模式使用的场景

比如线程池、全局缓存等。我们所熟知的浏览器的window对象就是一个单例,在JavaScript开发中,对于这种只需要一个的对象,我们的实现往往使用单例。

实现单例模式 (不透明的)

一般我们是这样实现单例的,用一个变量来标志当前的类已经创建过对象,如果下次获取当前类的实例时,直接返回之前创建的对象即可。代码如下:

  1. // 定义一个类
  2. function Singleton(name) {
  3. this.name = name;
  4. this.instance = null;
  5. }
  6. // 原型扩展类的一个方法getName()
  7. Singleton.prototype.getName = function() {
  8. console.log(this.name)
  9. };
  10. // 获取类的实例
  11. Singleton.getInstance = function(name) {
  12. if(!this.instance) {
  13. this.instance = new Singleton(name);
  14. }
  15. return this.instance
  16. };
  17. // 获取对象1
  18. var a = Singleton.getInstance('a');
  19. // 获取对象2
  20. var b = Singleton.getInstance('b');
  21. // 进行比较
  22. console.log(a === b);
  23. 我们也可以使用闭包来实现:
  24. function Singleton(name) {
  25. this.name = name;
  26. }
  27. // 原型扩展类的一个方法getName()
  28. Singleton.prototype.getName = function() {
  29. console.log(this.name)
  30. };
  31. // 获取类的实例
  32. Singleton.getInstance = (function() {
  33. var instance = null;
  34. return function(name) {
  35. if(!this.instance) {
  36. this.instance = new Singleton(name);
  37. }
  38. return this.instance
  39. }
  40. })();
  41. // 获取对象1
  42. var a = Singleton.getInstance('a');
  43. // 获取对象2
  44. var b = Singleton.getInstance('b');
  45. // 进行比较
  46. console.log(a === b);

知识点总结:

getInstance是类的静态方法,它里面的this指向类。类构造函数或者实例方法或者原型链上方法里的this指向类的实例。
image.png

  1. function Singleton(name) {
  2. this.name = name;
  3. }
  4. // 原型扩展类的一个方法getName()
  5. Singleton.prototype.getName = function() {
  6. console.log(this.name)
  7. };
  8. // 获取类的实例
  9. Singleton.getInstance = (function(){
  10. var instance = null;
  11. return function (name) {
  12. if(!this.instance) {
  13. this.instance = new Singleton(name);
  14. }
  15. return this.instance;
  16. }
  17. })()
  18. // 获取对象1
  19. var a = Singleton.getInstance('a');
  20. // 获取对象2
  21. var b = Singleton.getInstance('b');
  22. // 进行比较
  23. console.log(a === b);

这个单例实现获取对象的方式经常见于新手的写法,这种方式获取对象虽然简单,但是这种实现方式不透明。知道的人可以通过 Singleton.getInstance() 获取对象,不知道的需要研究代码的实现,这样不好。这与我们常见的用 new 关键字来获取对象有出入,实际意义不大。
**