单例模式

image.png

es6

  1. // 浏览器window就是一个典型的单例模式
  2. class Window {
  3. constructor(name) {
  4. this.name = name; 私有属性,即不能通过new Window创建实例
  5. }
  6. static getInstance(name) {// 可以Window类的静态方法拿到实例
  7. if (!this.instance) {
  8. this.instance = new Window(name);
  9. }
  10. return this.instance;
  11. }
  12. }
  13. var w1 = Window.getInstance();
  14. var w2 = Window.getInstance();
  15. console.log(w1 === w2);

es5

  1. let Window = function(name) {
  2. this.name=name;
  3. }
  4. Window.prototype.getName=function () { // 实例的方法
  5. console.log(this.name);
  6. }
  7. Window.getInstance=(function () { // 类上的方法,可以通过类来访问,而不能通过实例访问
  8. let window=null;
  9. return function (name) {
  10. if (!window)
  11. window=new Window(name);
  12. return window;
  13. }
  14. })();
  15. let window=Window.getInstance('zfpx');
  16. window.getName();
  17. //这样的写法存在两个问题
  18. /*
  19. 客户端,就是主动调用者必须知道这是一个单例的类,必须主动调用getInstance
  20. 并不能真正阻止客户端new这个类
  21. 解决:
  22. 1. 可以直接new ,但是它还是单例的(透明单例)
  23. */

透明单例

  1. let Window=(function () {
  2. let window;
  3. let Window=function (name) {
  4. if (window) {
  5. return window;
  6. } else {
  7. this.name=name;
  8. return (window=this);
  9. }
  10. }
  11. Window.prototype.getName=function () {
  12. console.log(this.name);
  13. }
  14. return Window;
  15. })();
  16. let window1=new Window('zfpx');
  17. let window2=new Window('zfpx');
  18. window1.getName();
  19. console.log(window1 === window2)

单例与构建分开

  1. function Window(name) {
  2. this.name=name;
  3. }
  4. Window.prototype.getName=function () {
  5. console.log(this.name);
  6. }
  7. let createSingle=(function () {
  8. let instance;
  9. return function (name) {
  10. if (!instance) {
  11. instance=new Window();// 存在问题:写死了,如果需要创建一个新的类,这这个方法需要载写一份
  12. }
  13. return instance;
  14. }
  15. })();
  16. //////////////
  17. function Dialog(name) {
  18. this.name=name;
  19. }
  20. let createSingle=(function () {
  21. let instance;
  22. return function (name) {
  23. if (!instance) {
  24. instance=new Dialog();// 存在问题:写死了,如果需要创建一个新的类,这这个方法需要载写一份
  25. }
  26. return instance;
  27. }
  28. })();
  29. let window1=new createSingle('zfpx');
  30. let window2=new createSingle('zfpx');
  31. window1.getName();
  32. console.log(window1 === window2)
  1. function Window(name) {
  2. this.name=name;
  3. }
  4. Window.prototype.getName=function () {
  5. console.log(this.name);
  6. }
  7. let createSingle=function (Constructor) {
  8. let instance;
  9. return function () {
  10. if (!instance) {
  11. Constructor.apply(this,arguments);
  12. //this._proto_ = Constructor.prototype
  13. Object.setPrototypeOf(this,Constructor.prototype)
  14. instance=this;
  15. }
  16. return instance;
  17. }
  18. };
  19. let CreateWindow=createSingle(Window);
  20. let window1=new CreateWindow('zfpx');
  21. let window2=new CreateWindow('zfpx');
  22. window1.getName();
  23. console.log(window1 === window2)