JavaScript中利用Symbol实现单例模式的属性锁定

Symbol 实现单例模式的核心是利用其唯一性和不可枚举性隔离实例引用,防止外部篡改或重复创建:通过 Symbol 键缓存实例(如静态属性或 WeakMap),并用 Object.defineProperty 锁定私有状态字段,但 Symbol 仅提供命名隔离,非绝对私有。用 Symbol 实现单例模式的属性锁定,核心是利用其唯一性和不可枚举性,防止外部篡改或重复创建实例。关键不在"锁住属性",而在于"隔离实例引用"------让构造函数只能返回同一个对象,且该对象的关键字段(如私有状态)不被外部覆盖或遍历。用 Symbol 作为私有实例缓存键将单例实例存在闭包或全局弱映射中,但用 Symbol 作键可避免被 for...in、Object.keys() 等枚举到,也不与字符串键冲突:在类外部声明一个 Symbol,用于存储唯一实例 构造函数检查该 Symbol 对应的值是否存在;若已存在,直接返回,不再新建 实例本身不暴露该 Symbol,外部无法通过点语法或方括号访问(除非拿到 Symbol 引用)示例:const INSTANCE = Symbol('singletonInstance');class Logger { constructor() { if (LoggerINSTANCE) { return LoggerINSTANCE; } LoggerINSTANCE = this; this.logCount = 0; } log(msg) { console.log(`${++this.logCount} ${msg}`); }}配合 WeakMap 实现更安全的实例绑定直接挂载在类上(如 LoggerINSTANCE)虽简单,但存在被手动删除或覆盖的风险。用 WeakMap + Symbol 可进一步解耦:用 Symbol 作为 WeakMap 的键标识符(仅作逻辑区分,实际仍用 WeakMap 的 set/get) 把类本身作为 WeakMap 的键,实例作为值,确保每个类独享单例 WeakMap 的键必须是对象,且不阻止垃圾回收,比静态属性更健壮改进写法:const INSTANCE_KEY = Symbol('instanceKey');const instances = new WeakMap();class Database { constructor() { if (instances.has(this.constructor)) { return instances.get(this.constructor); } instances.set(this.constructor, this); this.connected = false; } connect() { this.connected = true; }}防止原型/实例属性被意外覆盖单例对象的内部状态(如 this._cache)容易被外部赋值覆盖。可用 Symbol 命名私有字段,并配合 Object.defineProperty 锁定: Mokker AI AI产品图添加背景

相关推荐
懂点Tech2 小时前
ctfshow misc28:GIF 高度修改解题与脚本实现
开发语言·windows·python
comedate2 小时前
SMLib 的 Examples 导读:PyAPI / SM_API / SMLib 三组示例怎么读
python·cad·smlib·examples·sm_api
云和数据.ChenGuang2 小时前
Python 重写(Override)深度解析:从 MRO 到 super() 的完整机制
java·开发语言·人工智能·python·langchain·1024程序员节
摇滚侠3 小时前
《On Java 中文版 基础卷》阅读笔记 实现隐藏 12
java·数据库·笔记
川石课堂软件测试3 小时前
学习软件测试需掌握的一些知识
数据库·python·sql·功能测试·网络协议·mysql·http
万化冥合4 小时前
PyBox屏幕键盘如何辅助演示键盘操作?
python·计算机外设
车软学堂4 小时前
从测试转开发,到底要补什么
网络·人工智能·python·功能测试·单片机·车载系统·自动化
天空依然蔚蓝4 小时前
分享一个自动检测网站在线状态的python程序
python·运维开发·1024程序员节
2501_937767164 小时前
自建 SQL 数据库定时备份踩坑复盘与落地思路
数据库·sql
岁月宁静4 小时前
一个 AI 项目从本地到上线,要经过哪些步骤?全流程讲清楚
python·docker·agent