JavaScript實(shí)現(xiàn)單例模式的六種方式
JavaScript 中的單例模式確保一個(gè)類只有一個(gè)實(shí)例,并提供全局訪問(wèn)點(diǎn)。以下是幾種常見的實(shí)現(xiàn)方式:
1.對(duì)象字面量(最簡(jiǎn)單的方式)
const Singleton = {
property: 'value',
method() {
// 使用 this(在方法被解構(gòu)調(diào)用時(shí)會(huì)丟失上下文)
// console.log(this.property);
// 使用 Singleton(更安全)
console.log(Singleton.property);
}
};
// 使用
Singleton.method();
JavaScript 可以使用對(duì)象字面量快速創(chuàng)建一個(gè)對(duì)象,創(chuàng)建的對(duì)象本身就是單例。這種方式最為簡(jiǎn)單,但是需要注意 this 的引用可能出問(wèn)題。
為了解決 this 的問(wèn)題,可以直接引用單例對(duì)象本身。
2.閉包實(shí)現(xiàn)
const Singleton = (function() {
let instance;
function createInstance() {
const object = new Object('I am the instance');
return object;
}
return {
getInstance: function() {
if (!instance) {
instance = createInstance();
}
return instance;
}
};
})();
// 使用
const instance1 = Singleton.getInstance();
這里利用了閉包的特性實(shí)現(xiàn)了模塊的封裝和單例對(duì)象的引用,返回一個(gè) getInstance 方法用于獲取實(shí)例對(duì)象。
3.ES6 Class 實(shí)現(xiàn)
class Singleton {
constructor() {
if (Singleton.instance) {
return Singleton.instance;
}
this.data = 'Singleton Data';
Singleton.instance = this;
}
getData() {
return this.data;
}
setData(data) {
this.data = data;
}
}
// 使用
const s1 = new Singleton();
const s2 = new Singleton();
console.log(s1 === s2); // true
s1.setData('New Data');
console.log(s2.getData()); // 'New Data'
這里的 instance 是一個(gè)靜態(tài)變量,這種方式在 constructor 的最后將 this 賦值給 instance。
4.改進(jìn)的 class 實(shí)現(xiàn)(typescript 版本)
class Singleton {
private static instance?: Singleton;
private constructor() {}
static getInstance() {
if (!Singleton.instance) {
Singleton.instance = new Singleton();
}
return Singleton.instance;
}
}
// 使用
const s1 = Singleton.getInstance();
const s2 = Singleton.getInstance();
console.log(s1 === s2); // true
typescript 版本抽取 getInstance 方法,讓代碼更可讀。使用 private 關(guān)鍵字實(shí)現(xiàn)私有屬性和方法,保證代碼不會(huì)被隨意篡改。
5.ES6 模塊模式的單例
// 在模塊文件中
let instance = null;
class Database {
constructor(config) {
if (instance) {
return instance;
}
this.connection = this.connect(config);
instance = this;
}
connect(config) {
return { connected: true, config };
}
}
// 導(dǎo)出一個(gè)獲取實(shí)例的函數(shù)
export const getInstance= (() => {
let instance = null;
return (config) => {
if (!instance) {
instance = new Database(config);
}
return instance;
};
})();
這種方式利用 ES6 模塊變量的引用共享特性,保證 instance 唯一。導(dǎo)出一個(gè) getInstance 方法。
6.ES6 模塊本身就是單例
class Database {
constructor(config) {
this.connection = this.connect(config);
}
connect(config) {
return { connected: true, config };
}
}
// 直接導(dǎo)出一個(gè)實(shí)例
export default new Database({ host: 'localhost' });
實(shí)測(cè)證明,導(dǎo)出的實(shí)例在多個(gè)模塊間是共享的。
總結(jié)
JavaScript 實(shí)現(xiàn)單例模式的方式很多,這里介紹常用的6種,主要分4大類:對(duì)象字面量、閉包實(shí)現(xiàn)、 ES6 class 實(shí)現(xiàn)、ES6 模塊模式實(shí)現(xiàn)。
選擇哪種實(shí)現(xiàn)方式取決于具體需求,簡(jiǎn)單場(chǎng)景可以使用對(duì)象字面量,復(fù)雜場(chǎng)景建議使用 ES6 Class 或 ES6 模塊模式實(shí)現(xiàn)。
以上就是JavaScript實(shí)現(xiàn)單例模式的六種方式的詳細(xì)內(nèi)容,更多關(guān)于JavaScript實(shí)現(xiàn)單例模式的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
JS的鼠標(biāo)監(jiān)聽mouseup鼠標(biāo)抬起失效原因及解決
這篇文章主要為大家介紹了JS的鼠標(biāo)監(jiān)聽mouseup鼠標(biāo)抬起失效原因及解決示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-05-05
前端首屏加載速度性能優(yōu)化的實(shí)戰(zhàn)指南
首屏加載速度是衡量網(wǎng)站用戶體驗(yàn)的關(guān)鍵指標(biāo),本文將分享幾個(gè)在實(shí)際項(xiàng)目中總結(jié)的性能優(yōu)化方案,幫助你的網(wǎng)站首屏加載速度提升80%,大家可以根據(jù)需要進(jìn)行選擇2025-11-11
阻止mousemove鼠標(biāo)移動(dòng)或touchmove觸摸移動(dòng)觸發(fā)click點(diǎn)擊事件
這篇文章主要為大家介紹了阻止mousemove或touchmove與click事件同時(shí)觸發(fā)技巧,一個(gè)按鈕綁定了多個(gè)事件,所以就要想辦法阻止 mouse 鼠標(biāo)事件或 touch 觸摸事件 與 click 事件同時(shí)觸發(fā),不然每次拖拽按鈕后都會(huì)觸發(fā) click 事件,這顯然是不友好的2023-06-06
Layer彈出層動(dòng)態(tài)獲取數(shù)據(jù)的方法
今天小編就為大家分享一篇Layer彈出層動(dòng)態(tài)獲取數(shù)據(jù)的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-08-08
JavaScript使用DeviceOne開發(fā)實(shí)戰(zhàn)(一) 配置和起步
這篇文章主要介紹了JavaScript使用DeviceOne開發(fā)實(shí)戰(zhàn)(一) 配置和起步的相關(guān)資料,需要的朋友可以參考下2015-12-12
使用js獲取地址欄參數(shù)的方法推薦(超級(jí)簡(jiǎn)單)
下面小編就為大家?guī)?lái)一篇使用js獲取地址欄參數(shù)的方法推薦(超級(jí)簡(jiǎn)單)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2016-06-06

