JavaScript 设计模式之单例模式

85 阅读2分钟

纯JavaScript版本的设计模式之单例模式。

定义

只有一个实例对象,并提供全局访问。

是一种创建型设计模式。

实践

全局变量

满足单例模式的两个条件:

此方式创建对象Message,唯一;

声明在全局作用域下,可以在任何地方使用此对象。

const Message = {
    name: "JavaScript
}

《JavaScript设计模式与开发实践》 4.4章节中说“全局变量不是单例模式”,原因是“全局变量存在很多问题,它很容易造成命名空间污染”。书中示例: var a = {}。

个人理解:此书是2015年05月出版的,ES6规范是2015年06月正式发布的,说明当时还没有const。ES6规范之后,用const声明的变量不能被重新赋值,就不存在书中说的问题。所以,我觉得全局变量是单例模式的一种,有没有不同的声音呢?

单例对象

惰性单例:在需要的时候才创建对象实例。

创建对象:

const CreateMessage = () => {
    const div = document.createElement("div");
    div.innerText = "Hello";
    div.style.display = "none";
    document.body.appendChild(div);
    return div;
};

使用:

const click = ()=> {
    // 惰性,点击之后才会创建Message
    const div = CreateMessage();
    div.style.display = "block";
}
 
// 点击按钮 3次
click();

// 创建了三个 “Hello” div

预期: 我想要每次点击,只创建一个Message。

管理单例(通用):

// 高阶函数
const getSingle = function (fn) {
    let result;
    // 闭包
    return function () {
        return result || (result = fn.apply(this, arguments));
    };
};

使用:

// 代理模式, 创建单例函数
const MessageModal = getSingle(CreateMessage);

const click = ()=> {
    // 惰性,点击之后才会创建Message
    const div = MessageModal();
    div.style.display = "block";
}

// 点击按钮 3次
click();

只会创建一个“Hello” div

总结

单例模式是一种简单且非常实用的设计模式。很多对象只需要创建一次,并且在需要的时候创建,便可以选用此模式。