浅谈Symbol()和Symbol.for()创建的区别

本文探讨了如何Symbol()函数创建的唯一标识符在比较时可能不相等,而Symbol.for()方法确保生成的Symbol在注册表中保持唯一,解释了两者的实现原理及为何结果不同。

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

Symbol()创建的值不相等而Symbol.for()创建的值相等,为什么?

先上例子:
1、用Symbol() 创建

<script>
    // let s = Symbol();
    // console.log(s,typeof s);
    let s2 = Symbol('我是小米');
    let s3 = Symbol('我是小米');
    console.log(s2==s3);
</script>

控制台输出结果:
在这里插入图片描述
2、用Symbol.for() 创建

   <script>
    let s4 = Symbol.for("我是红豆");
    let s5 = Symbol.for("我是红豆");
    console.log(s4==s5);
</script>

控制台输出结果:
在这里插入图片描述
疑问:为什么会出现这种情况???

解答:
使用Symbol.for() 方法创建时,会将创建的Symbol存入一个全局的注册表中,在下次创建时,会首先从注册表中查找是否已有相同的值存在,如果没有,则创建;如果有,便不会创建重复的Symbol。

这也就是解答了 为什么使用Symbol.for() 创建的两个Symbol判断是否相等时,返回的时true。

### JavaScriptSymbol.for 的用法及其与私有属性的关系 #### 1. Symbol.for 的基本用法 `Symbol.for()` 方法用于从全局符号注册表中检索一个现有的符号,如果该符号存在,则会创建并返回一个新的符号。此方法接受一个字符串参数作为键名,该键名同时也是符号的描述信息[^4]。 ```javascript const sym1 = Symbol.for('sharedSymbol'); const sym2 = Symbol.for('sharedSymbol'); console.log(sym1 === sym2); // true ``` 通过上述代码可以看出,`Symbol.for()` 方法确保了同模块或文件中可以共享同一个符号,而 `Symbol()` 每次都会生成新的唯一符号[^3]。 #### 2. 创建全局共享符号的场景 在实际开发中,`Symbol.for()` 常用于需要跨模块或跨文件共享符号的场景。例如,多个文件可能需要访问同一个私有属性或标识符,此时可以使用 `Symbol.for()` 来确保符号的一致性。 以下是一个示例,展示如何在同模块中共享符号: **模块 A:** ```javascript export const sharedSymbol = Symbol.for('sharedKey'); ``` **模块 B:** ```javascript import { sharedSymbol } from './moduleA'; const obj = {}; obj[sharedSymbol] = 'Shared Value'; console.log(obj[sharedSymbol]); // 输出: Shared Value ``` 在这个例子中,模块 A 模块 B 通过 `Symbol.for('sharedKey')` 共享了同一个符号,从而实现了跨模块的数据共享[^4]。 #### 3. Symbol.for 与私有属性的关系 尽管 `Symbol.for()` 可以创建全局共享的符号,但它并适合用于严格意义上的私有属性。这是因为任何代码都可以通过 `Symbol.for()` 访问到全局注册表中的符号,因此这种“私有”属性实际上是可被外部代码访问的[^1]。 为了实现更严格的私有属性,通常推荐使用 `Symbol()` 而非 `Symbol.for()`。`Symbol()` 创建的符号是完全唯一的,无法通过其他方式访问,从而更好地保护私有属性[^5]。 ```javascript const privateField = Symbol(); class MyClass { constructor(value) { this[privateField] = value; } getPrivateValue() { return this[privateField]; } } const instance = new MyClass('Secret Value'); console.log(instance.getPrivateValue()); // 输出: Secret Value console.log(instance[privateField]); // 报错:privateField 是未定义的 ``` 在此示例中,`privateField` 是通过 `Symbol()` 创建的,因此它会出现在全局注册表中,也无法被外部代码轻易访问[^5]。 #### 4. 总结 - 使用 `Symbol.for()` 可以创建全局共享的符号,适用于需要跨模块或文件共享符号的场景。 - 对于严格意义上的私有属性,推荐使用 `Symbol()`,因为它生成的符号是完全唯一的,无法被外部代码访问。 - 需要注意的是,即使使用 `Symbol()` 创建的私有属性,仍然可以通过直接引用符号的方式访问,因此并非绝对安全。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值