GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Complete JavaScript
  • JavaScript
  • React
  • Question
  • Freebie
  • Blog
  • eBooks
  • Snippets
  • Tools

This view

  • Original page
  • New address

GeezerVison is showing completejavascript.com — JS Pattern #3 - Singleton Pattern

Trang chủ › JavaScript › JS Pattern #3 - Singleton Pattern
Cập nhật ngày 02/04/2018

Có thể bạn đã nghe quen về Singleton. Singleton Pattern giới hạn số lượng instance của một class là một. Trong JavaScript, bạn có thể triển khai Singleton Pattern theo cách sau.

Singleton Pattern cơ bản

var mySingleton = (function () {
  var instance;
  function init() {
    var number = 0;
    return {
      setNumber: function (x) {
        number = x;
      },
      getNumber: function () {
        return number;
      },
    };
  }

  return {
    getInstance: function () {
      if (!instance) instance = init();
      return instance;
    },
  };
})();

var instA = mySingleton.getInstance();
console.log("instance A: ", instA.getNumber()); // instance A: 0
instA.setNumber(10);
console.log("instance A: ", instA.getNumber()); // instance A: 10

var instB = mySingleton.getInstance();
console.log("instance B: ", instB.getNumber()); // instance B: 10

console.log(instA === instB); // true

Giải thích

Các bạn có thể thấy, cách triển khai Singleton trên rất giống với Module Pattern. Chỉ có một chú ý là, mySingleton chỉ có một access point duy nhất là getInstance. Vậy tại sao khi sử dụng function này thì ta chỉ thu được một instance duy nhất?

Đúng vậy, ban đầu khi chưa gọi getInstance lần nào thì biến instance sẽ là undefined. Lúc này, instance sẽ được khởi tạo bằng cách sử dụng hàm số init. Cuối cùng, hàm số trả về biến instance. Đối với các lần gọi getInstance tiếp theo, vì instance đã khác undefined nên nó sẽ không được tạo mới mà sẽ return ngay lập tức.

Như ví dụ trên, instA khi mới tạo ra thì getNumber sẽ trả về 0. Trong khi, instB khi mới tạo ra thì getNumber trả về 10 - giá trị này được set ở instA trước đó. Và quan trọng hơn, instA === instB trả về giá trị true. Như vậy, thực chất instB cũng chính là instA.

Singleton with a cached static property

function User() {
  // do we have an existing instance?
  if (typeof User.instance === "object") {
    return User.instance;
  }

  // proceed as normal
  this.firstName = "John";
  this.lastName = "Doe";

  // cache
  User.instance = this;

  /**
   * // implicit return
   * return this;
   */
}

// Usage:
var curUser = new User();
console.log(curUser.firstName, curUser.lastName); // John Doe

var other = new User();
console.log(other.firstName, other.lastName); // John Doe
console.log(other === curUser); // true

Cách này khi mới đọc thì sẽ thấy hơi ảo, ở chỗ là, trong hàm User ta lại sử dụng User.instance. Nhưng nếu nhìn theo khía cạnh, function cũng chính là một object thì mọi chuyện sẽ trở nên đơn giản.

Như trong ví dụ trên, khi khởi tạo curUser (lần đầu tiên), User.instance đang có giá trị là undefined, nên mọi thứ được xử lý như bình thường. Khi kết thúc hàm, ta gán User.instance = this hay nói cách khác là User.instance = curUser. Đến khi khởi tạo đối tượng thứ hai là other, lúc này User.instance đã là curUser - một object, nên hàm trên sẽ return về User.instance (curUser). Đó, dù có gọi hàm khởi tạo bao nhiêu lần thì ta cũng chỉ thu được một đối tượng duy nhất.

Xin chào và hẹn gặp lại bạn ở bài viết tiếp theo, thân ái!

Tham khảo

  • Learning JavaScript Design Patterns
  • JavaScript Design Pattern Singleton

★ Nếu bạn thấy bài viết này hay thì hãy theo dõi mình trên Facebook để nhận được thông báo khi có bài viết mới nhất nhé:

  • Facebook Fanpage: Complete JavaScript
  • Facebook Group: Hỏi đáp JavaScript VN
JavaScript
IIFE, Design Pattern
JS Pattern #2 - Module Pattern
JS Pattern #4 - PubSub Pattern
Chia sẻ:

Bình luận

Bài viết mới cập nhật

Cách chọn CMS cho trang webAsync/await là gì? Async/await trong JSMicrotasks là gì? Microtasks trong JSChuyển callback thành promise trong JSCác promise API trong JavaScriptXử lý lỗi với promise trong JavaScriptChuỗi promise trong JavaScriptPromise là gì? Promise trong JavaScriptCallback là gì? Callback trong JavaScriptTùy biến và mở rộng đối tượng Error trong JS
You are visitor 01402520 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.