JavaScript ECMAScript 6中Symbol的用途是什么?示例为何返回false?
Symbol('foo') === Symbol('foo')返回false的原因 嘿,这个问题问得很到位!让我来给你把Symbol的作用和这个相等性问题讲明白~
Symbol的核心用途
Symbol是ES6新增的原始数据类型,它的设计初衷就是为了解决JavaScript里长期存在的一些命名冲突和行为定制问题,主要有这几个关键场景:
创建唯一的对象属性键
当多个模块、库需要给同一个对象添加属性时,用字符串作为键很容易出现命名冲突。而每个Symbol都是独一无二的,用它作为属性键就完全不用担心这个问题。比如:const moduleAKey = Symbol('moduleA'); const moduleBKey = Symbol('moduleB'); const sharedObj = {}; sharedObj[moduleAKey] = '模块A的专属数据'; sharedObj[moduleBKey] = '模块B的专属数据'; // 两者完全不会互相覆盖自定义内置对象的行为
ES6提供了一系列内置Symbol常量,用来让我们自定义对象的原生行为。比如:Symbol.iterator:给对象添加迭代器,让它可以用for...of循环遍历;Symbol.toStringTag:自定义Object.prototype.toString.call(obj)的返回结果,比如让你的自定义对象返回[class MyCustomObj];Symbol.hasInstance:自定义instanceof操作符的判断逻辑。
模拟私有属性
Symbol作为对象的属性键时,不会被for...in、Object.keys()、Object.getOwnPropertyNames()这些常规遍历方法枚举到,只有通过Object.getOwnPropertySymbols()才能获取到。这就可以用来模拟“私有属性”,虽然不是真正的私有(还是能被访问到),但能避免被意外遍历或修改,起到类似私有属性的作用。
为什么Symbol('foo') === Symbol('foo')返回false?
答案很简单:每一次调用Symbol()(不管有没有传描述参数)都会生成一个全新的、独一无二的Symbol实例。
你传入的'foo'只是这个Symbol的描述字符串,它唯一的作用就是方便调试(比如在控制台打印这个Symbol时会显示这个描述),完全不影响Symbol的唯一性。所以哪怕两个Symbol的描述一模一样,它们也是完全不同的两个值,自然不会相等。
如果想要复用同一个Symbol值,可以用Symbol.for()方法——它会维护一个全局的Symbol注册表:
console.log(Symbol.for('foo') === Symbol.for('foo')); // 输出: true
第一次调用Symbol.for('foo')时会创建一个新的Symbol并注册到全局表,第二次调用时会直接返回之前创建的那个Symbol,所以两者相等。
内容的提问来源于stack exchange,提问作者Mohamed Ben HEnda

