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产品图添加背景
相关推荐
TDengine (老段)1 小时前
TDengine 常见问题 TOP3troy1282 小时前
Python 基础语法(九):Django/Flask/FastAPI 三大 Web 框架详细对比解析jzshmyt2 小时前
我用 Python 从零“生成“了一个宇宙,然后让它观察自己(v14)螺蛳粉 螺蛳粉4 小时前
MySQL 分布式集群系列 · 第五篇——全方位对比:NDB、MGR、主从复制、分库分表怎么选?用户8356290780514 小时前
使用 Python 将 DOCX 转换为 Markdown小玮看世界4 小时前
[Python]ADAS工程实战(三):多传感器扇区统计疑难点全解——归一化、跨边界、去重与置信度TomEval5 小时前
【测AI】第02篇:Python 环境搭建与基础语法速通归去来 兮5 小时前
LangChain从入门到精通淘气的小猴子6 小时前
Python 魔术方法入门我要见SA姐16 小时前
DeepSeek Harness 开源贡献手记:从 Issue 到 Merge 的完整旅程