为什么 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类型的值,所以不等是必然的,和他们的执行顺序无关。

浙公网安备 33010602011771号