为什么 Symbol("test") !== Symbol.for("test")

为了帮助我们理解Symbol,在浏览器控制它进行以下测试:

Symbol("test") == Symbol.for("test")
// false
Symbol.for("test") == Symbol.for("test")
// true 

根据结果,我们看出Symbol("test") !== Symbol.for("test") ,那么为什么呢?

首先我们需要知道:
在 JavaScript 中,Symbol 是一种基本类型,常用于创建独一无二且不可变的标识符。Symbol("test")Symbol.for("test") 虽然都创建了 Symbol,但它们的行为和用途有所不同:

  1. Symbol("test"):

    • 这是一个普通的 Symbol,它是唯一的,不会和其他任何 Symbol 相等,即使它们使用相同的描述符。
    • 每次调用 Symbol("test") 都会创建一个新的 Symbol 实例。
  2. Symbol.for("test"):

    • 这是一个全局注册的 Symbol,它会在一个全局的 Symbol 注册表中查找是否已经有描述符为 "test"Symbol
    • 如果存在,则返回该全局 Symbol;如果不存在,则创建一个新的 Symbol 并将其添加到全局注册表中。

因此:

  • Symbol("test") == Symbol("test") 返回 false,因为每次调用 Symbol("test") 都会创建一个新的、独一无二的 Symbol,它们彼此不相等。

  • Symbol.for("test") == Symbol.for("test") 返回 true,因为 Symbol.for 会在全局注册表中查找并返回同一个 Symbol,只要描述符相同。

总结:

  • 使用 Symbol("test") 是为了创建一个局部的、唯一的 Symbol
  • 使用 Symbol.for("test") 是为了在全局范围内共享一个唯一的 Symbol

但是现在疑问出现了,根据我们既往的经验,出现了局部、全局等概念,我们是不是可以用作用域来理解呢?

其实并不可以,为什么不可以,我们细看:

Symbol("test")Symbol.for("test") 之间的不等同于作用域的问题,而在于它们的创建和存储机制的不同。

Symbol("test")

  • 局部唯一:每次调用 Symbol("test") 都会创建一个新的、独一无二的 Symbol。即使它们使用了相同的描述符("test"),这些 Symbol 也不会相等。
  • 不在全局注册表中存储Symbol("test") 创建的 Symbol 不会被存储在全局注册表中。因此,调用 Symbol("test") 时,总是创建一个新的 Symbol 实例,而不会进行任何全局查找

Symbol.for("test")

  • 全局唯一Symbol.for("test") 会在一个全局的 Symbol 注册表中查找是否已经存在描述符为 "test"Symbol
  • 全局注册表:如果在全局注册表中找到描述符为 "test"Symbol,则返回该 Symbol;如果找不到,则创建一个新的 Symbol 并将其存储在全局注册表中,以后对 Symbol.for("test") 的调用都会返回同一个 Symbol

为什么 Symbol("test")Symbol.for("test") 不相等?

  • Symbol("test") 创建的 Symbol 是局部的,独一无二的,不会被存储在全局注册表中,也不会从全局注册表中查找。
  • Symbol.for("test") 创建或返回的 Symbol 是在全局注册表中查找和存储的,因此它是全局唯一的。

当你调用 Symbol("test") 时,它并不会去检查或使用全局注册表,而是直接创建一个新的、唯一的 Symbol。因此,即使在全局注册表中已经存在一个描述符为 "test"SymbolSymbol("test") 仍然会创建一个新的 Symbol 实例。

当你调用 Symbol.for("test") 时,它会首先在全局注册表中查找,如果找到匹配的 Symbol,则返回该 Symbol;如果找不到,则创建一个新的 Symbol 并将其存储在全局注册表中。

因此,Symbol("test")Symbol.for("test") 是两种不同的机制,导致它们创建的 Symbol 不相等。

附:

其实在思考这个问题的时候,也设想过是不是执行顺序的问也就是:Symbol("test") == Symbol.for("test")和Symbol.for("test")==Symbol("test") 是不是一样的,一个先创建后查找,一个先查找、创建,然后创建。

在明白两者机制不同之后,答案自然也就清楚了,两者考虑的并不是同一范围,Symbol("test")根本不会查找而是直接创建,Symbol.for("test")查找的范围也不包括Symbol("test")所在范围,所以二者的值并不相关,而是各自独立的。所以也就自然不等。因为它们都是各自创建了一个Symbol类型的值,所以不等是必然的,和他们的执行顺序无关。

posted @   胡安  阅读(11)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
点击右上角即可分享
微信分享提示