Symbol是唯一键,用于避免属性名冲突;BigInt解决整数精度丢失问题,二者均非万能解,需依场景选用。

Symbol 是用来避免属性名冲突的唯一键
当你往一个对象里加属性,又不确定它原本有没有同名字段时,用字符串当 key 很容易覆盖别人的数据。Symbol 就是专治这个的:每次调用 Symbol() 都生成一个全局唯一的值,哪怕描述一样,也不相等。
-
Symbol('id')和Symbol('id')两个值不相等 —— 它们只是“长得像”,本质不同 - 想跨模块复用同一个 Symbol?用
Symbol.for('id'),它会查全局注册表,相同字符串返回同一个 Symbol - 对象上用 Symbol 当 key,
Object.keys()、for...in都看不到它,得用Object.getOwnPropertySymbols()单独捞 - 别试图把 Symbol 转成数字或字符串再参与运算 ——
Number(sym)会报错,String(sym)只能得"Symbol(description)"这种调试串
BigInt 解决的是整数精度丢失问题
JavaScript 的 Number 类型安全上限是 2**53 - 1(即 9007199254740991),超过这个数,加 1 可能没反应,比如 9007199254740992 + 1 === 9007199254740992。BigInt 就是为这种场景生的。
- 创建方式只有两种:
123456789012345678901234567890n(带n后缀)或BigInt("123...")(字符串入参,不能传小数) -
typeof 100n返回"bigint",但100n === 100是false,两者类型不同,不能混用 - 所有算术运算符(
+、-、*、**)都支持 BigInt,但/和%会向下取整(无小数),且10n / 3n得3n,不是3.333... - 和
Number混合运算直接报错:10n + 1→TypeError;必须显式转换:10n + BigInt(1)
它们都不是“私有”或“大数万能解”
有人以为 Symbol 能当私有属性用,或者 BigInt 能替代所有数字场景 —— 这是常见误读。
- Symbol 不等于私有:外部只要拿到那个 Symbol 实例(比如通过
Object.getOwnPropertySymbols()暴露、或你导出了它),照样能读写对应属性 - BigInt 不支持小数、不能用于
Math方法(Math.sqrt(100n)报错)、不能当数组索引(arr[100n]会被转成字符串"100")、JSON 序列化直接忽略(JSON.stringify({x: 100n})报错) -
浏览器兼容性要查实:
Symbol在 IE 全系不支持;BigInt在 Safari 14+、Chrome 67+、Firefox 68+ 才可用,Node.js 从 v10.4.0 开始支持,但需开启--harmony-bigint标志(v10.7.0+ 默认启用)
什么时候该用,什么时候不该用
选型不是看新不新,而是看它是否真解决你手头的问题。
立即学习“Java免费学习笔记(深入)”;
- 用
Symbol:定义常量枚举(const STATUS_PENDING = Symbol('pending'))、给第三方对象打标记(不污染原 key 空间)、实现轻量级“命名空间”逻辑 - 用
BigInt:处理数据库 long 型 ID(如 Twitter 的 Snowflake ID)、密码学运算、高精度计数器(比如区块链 nonce)、时间戳纳秒级精度(Date.now() * 1000000n) - 别用
Symbol:想真正隐藏数据、做访问控制 —— 应该用#privateField(ES2022 私有字段)或闭包 - 别用
BigInt:需要浮点计算、要进 JSON、要和 DOM API 交互(比如setTimeout(100n, ...)会失败)、性能敏感循环中频繁创建(BigInt创建比Number重)
真正难的不是记住语法,而是判断某个业务字段到底“是不是必须唯一”、某个数字“是不是真的会超安全整数范围”。很多时候,加个 console.log(Number.isSafeInteger(x)) 或翻下后端接口文档,比硬套新类型更管用。











