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产品图添加背景

相关推荐
瀚高PG实验室6 分钟前
HGHAC集群VIP-MANAGER挂载的VIP消失
数据库·postgresql·瀚高数据库
野生码农AI实战9 分钟前
AI 看不了网页?我用 CDP 重建浏览器采集通道,30 行脚本 2.7 秒读完全文
数据库·人工智能·ai编程
Mortalbreeze9 分钟前
MySQL 基础篇(六):聚合查询与分组查询
数据库·mysql
Omics Pro11 分钟前
反式感知虚拟细胞!超越线性序列
数据库·人工智能·算法·机器学习·自然语言处理
jianjinwssy19 分钟前
PostgreSQL 进阶:索引、MVCC、VACUUM 与 WAL
数据库·postgresql
天空鸟_时光不老28 分钟前
10-Agent安全隐患与SQL执行层加固
java·数据库·人工智能·sql·spring·maven·mybatis
JCHT1818181 小时前
源头厂家免拆维护:HT-6500H引领政企会议室革新
大数据·python
晚风叙码1 小时前
MySQL 表的约束详解:从空属性到外键
android·数据库·mysql·adb
rannn_1112 小时前
JVM 面试题:类加载过程详解(附高频考点)
java·jvm·后端
朝朝辞暮i9 小时前
VLA 系统学习第 4 课:一个 Batch 进入神经网络后,模型到底是怎么“学会”的?
人工智能·python·神经网络·vla