JavaScript 中的单例以及模块模式

本文介绍了JavaScript中单例的概念及实现方式,并详细探讨了如何使用闭包来创建私有变量和特权方法,最后讲解了模块模式在创建单例对象时的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、单例

单例指的是只有一个实例的对象,JavaScript以对象字面量的方式创建单例对象。

var singleton = {
    name: value,
    method: function(){
        //方法
    }
};


二、私有变量和公有(特权)方法

任何在函数中定义的变量,都可以认为是私有变量。私有变量包括函数的参数,局部变量和在函数内部定义的其他函数。

如果在函数内部创建一个闭包,那么闭包通过自己的作用域链也可以访问函数的私有变量。利用这一点,就可以创建访问私有变量的公有方法,也叫特权方法。

function Person(name){
            
    this.getName = function(){
        return name;
    };
            
    this.setName = function (value) {
        name = value;
    };
}
            
var person = new Person("latency");
alert(person.getName());   //"latency"
person.setName("cheng");
alert(person.getName());   //"cheng"
以上代码的构造函数中定义了两个特权方法:getName()和setName()。这两个方法都可以在构造函数外部使用,而且都有权访问私有变量name。但在Person构造函数外部,没有任何办法访问name。由于这两个方法是在构造函数内部定义的,它们作为闭包能够通过作用域链访问name。私有变量name在Person的毎一个实例中都不相同,因为每次调用构造数都会重新创建这两个方法。


三、模块模式

上面介绍的是为自定义类型创建私有变量和特权方法。模块模式则是为单例创建私有变量和特权方法。

var singleton = function(){

    //私有变量和函数    
    var privateVariable = 10;
    function privateFunction(){
        return false;
    }

    //特权方法和属性
    return {
        publicProperty : true,
        publicMethod: function(){
            privateVariable++;
            return privateFunction();
        }
    }
}();
这个模块模式使用了一个返回对象的匿名函数。在这个匿名函数内部,将一个对象字面量作为函数的值返回。其中包含可以公开的属性和方法。因为这个匿名函数是在函数内部定义的,所以可以访问私有的变量和函数。这个对象字面量定义的是单例的公共接口。

当必须要创建一个对象并以某些数据对其进行初始化,同时还要公开一些能够访问这些私有数据的方法时,就可以用模块模式。




<think>好的,我现在需要帮用户了解JavaScript中的模式的实现和应用场景。首先,我得回忆一下模式的基本概念,确保自己理解正确。模式确保一个类只有一个实,并提供全局访问点,这在需要共享资源或控制资源访问时非常有用。 接下来,我需要参考用户提供的四个引用资料。引用[1]提到模式的原理和实现方式,以及JavaScript中的应用场景。引用[2]讨论了基于闭包、类静态属性和模块化的实现方法。引用[3]举了JQuery的子,说明的实际应用。引用[4]则强调在全局作用域只创建一次实,并共享给所有调用点。 首先,我应该整理出模式的几种实现方式。根据引用[2],常见的实现包括闭包、类静态属性和ES6模块。我需要详细说明每种方法的代码示,确保用户能理解不同的实现方法之间的区别和适用场景。 然后,应用场景部分,引用[3]和[4]提到了全局状态管理、缓存、日志工具等。需要具体举,比如Vuex中的Store,或者缓存工具类,这样用户能更直观地理解何时使用模式。 同时,用户可能关心模式的优缺点,比如优点如资源节省、统一管理,缺点如测试困难、违反一职责原则。这些内容也需要涵盖进去,帮助用户全面评估是否适合使用。 在整理过程中,要注意引用资料中的关键点,比如闭包实现如何利用IIFE和内部变量保存实,ES6模块的天然特性。另外,JQuery的子可以具体说明模式在第三方库中的应用,增强实用性。 最后,生成相关问题时要围绕模式的扩展,比如优缺点对比、惰性实现、与静态类的区别、Vuex中的应用,以及如何防止破坏。这些问题能引导用户进一步深入学习,解决可能遇到的疑问。 需要确保回答结构清晰,分点说明实现方式和应用场景,每个部分都有代码示和实际案。同时,检查LaTeX格式是否正确,行内公式用$...$,独立公式用$$...$$,但在这个问题中可能涉及较少数学公式,主要注意代码块的格式和引用标识的位置。 总结步骤: 1. 定义模式及其目的。 2. 分点介绍实现方式,每种方式给出代码示。 3. 列举应用场景,结合实际案。 4. 分析优缺点。 5. 生成相关问题,覆盖实现细节、比较和应用。 在写作过程中,要确保语言简洁,符合中文表达习惯,引用标识自然添加在相关段落末尾。如,在提到闭包实现时引用[2],在讨论JQuery子时引用[3]。</think>### JavaScript 模式实现及应用场景 #### 一、模式的核心原理 模式通过限制类的实化次数为**1次**,并提供全局访问点,确保系统中仅存在**唯一实**。这种设计模式常用于管理全局资源(如配置对象、缓存池)或避免重复创建高成本对象[^1]。 #### 二、JavaScript 模式的实现方式 1. **闭包实现(惰性加载)** 利用闭包特性保存私有实变量,延迟实化直到首次调用: ```javascript const Singleton = (function () { let _instance = null; // 闭包内保存实 function _createInstance() { return { /* 业务逻辑 */ }; } return { getInstance: function () { if (!_instance) { _instance = _createInstance(); } return _instance; } }; })(); const s1 = Singleton.getInstance(); const s2 = Singleton.getInstance(); console.log(s1 === s2); // true [^2] ``` 2. **类静态属性实现** ES6 类语法结合静态属性直接控制实: ```javascript class Singleton { static _instance = null; constructor() { if (Singleton._instance) { throw new Error("禁止重复实化!"); } Singleton._instance = this; } static getInstance() { if (!this._instance) { this._instance = new Singleton(); } return this._instance; } } ``` 3. **ES6 模块化实现** ES6 模块天然支持模块加载时实化一次): ```javascript // singleton.js let instance = null; export default class Singleton { constructor() { if (!instance) instance = this; return instance; } } ``` #### 三、应用场景 1. **全局状态管理** 如 Vuex 的 Store 对象,确保应用全局状态唯一性[^3]。 2. **缓存池管理** 避免重复创建数据库连接池或 API 请求缓存: ```javascript const CacheManager = { _cache: new Map(), set(key, value) { this._cache.set(key, value); }, get(key) { return this._cache.get(key); } }; ``` 3. **第三方库实控制** JQuery 加载时通过避免重复初始化: ```javascript if (window.jQuery) return window.jQuery; else window.jQuery = initJQuery(); // ``` #### 四、优缺点分析 | **优点** | **缺点** | |-------------------------|-----------------------------| | 减少内存占用 | 测试困难(全局状态耦合) | | 统一管理共享资源 | 违反一职责原则 | | 避免重复初始化耗时操作 | 需处理多线程问题(非 JS) | #### §§ 相关问题 §\§ 1. 模式与静态类的本质区别是什么? 2. 如何实现支持**惰性加载**的模式? 3. 在 Vuex 中如何通过模式管理全局状态? 4. 模式可能违反哪些设计原则?如何规避? 5. 如何防止通过`Object.create()`或`new`操作符破坏
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值