为什么 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
,但它们的行为和用途有所不同:
-
Symbol("test")
:- 这是一个普通的
Symbol
,它是唯一的,不会和其他任何Symbol
相等,即使它们使用相同的描述符。 - 每次调用
Symbol("test")
都会创建一个新的Symbol
实例。
- 这是一个普通的
-
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"
的 Symbol
,Symbol("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类型的值,所以不等是必然的,和他们的执行顺序无关。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构