JavaScript中与Symbol类型值比较时必须使用严格相等===吗
结论
你的认知基本正确,仅存在一个极其冷门的边角场景例外,日常开发中几乎不会触发。
比较规则说明
按照ECMAScript标准中宽松相等==的比较逻辑,只要比较双方有一个是原始Symbol类型,就不会触发常见的跨原始类型隐式转换:
- 当两边类型不同、且其中一边是Symbol原始值时,不会像比较数字、字符串、布尔值那样执行强制类型转换,直接返回
false。类似Symbol('test') == 'test'、Symbol('1') == 1、Symbol('foo') == true这类写法全部返回false,不会出现意料之外的真值。 - 当两边都是原始Symbol类型时,判断逻辑和严格相等
===完全一致:只有两个值是同一个Symbol实例(包括Symbol.for()注册的同名全局Symbol)才会返回true;哪怕两个Symbol的描述字符串完全相同,只要是独立创建的不同实例,就会返回false。
唯一的行为差异点
==和===比较Symbol时,仅在碰到Symbol包装对象时行为不一致:
如果传入的x是通过Object(somePredefinedSymbol)创建的Symbol包装对象(属于object类型),==比较时会先把包装对象解包为内部存储的原始Symbol值,最终返回true;但===会因为两边类型不同(一个是object、一个是symbol)直接返回false。
注:Symbol包装对象是几乎没有实际使用场景的冷门语法,常规业务代码中几乎不会有人主动创建这类值,绝大多数开发场景下你根本碰不到这个差异。
对你给出代码的验证
你写的判断逻辑如下:
function foo(x) { return x == somePredefinedSymbol; }
排除主动传入Symbol包装对象的极端场景,这段代码确实只有在x本身就是somePredefinedSymbol这个原始Symbol值时才会返回true,不会出现其他隐式转换导致的非预期错误。
行业内普遍推荐始终用===比较Symbol,核心原因主要是统一代码风格,降低代码阅读者的心智负担,而非==在常规使用场景下存在逻辑漏洞。
内容的提问来源于stack exchange,提问作者Zoso
相关产品推荐
相关产品推荐

