返回

Symbol:ES6中的独特标识符

前端

ES6中引入了Symbol作为一种独特标识符。Symbol是一种不可变的原始类型,它可用于创建唯一标识符,从而避免了使用字符串作为属性名所带来的重复和冲突问题。

Symbol 的创建

const symbol1 = Symbol(); // 默认不传参会生成一个唯一的symbol值
const symbol2 = Symbol('symbol2'); // 可以传入字符串,但不能作为属性名使用

Symbol 的特点

  • 唯一性:Symbol 是独一无二的,没有两个 Symbol 对象是相等的。
  • 不可变性:Symbol 一旦创建,就不能再改变其值。
  • 全局唯一性:Symbol 是全局唯一的,即使在不同的作用域中创建,也是同一个 Symbol 对象。
  • 隐式类型转换:Symbol 不能参与隐式类型转换。
  • 不被枚举:Symbol 属性不会出现在 for-in 循环和 Object.keys() 方法的返回结果中。

Symbol 的应用

Symbol 可以用来实现各种场景中的唯一标识符,例如:

  • 对象的属性名
const person = {
  name: 'John',
  [Symbol('age')]: 30,
};

console.log(person.age); // undefined
console.log(person[Symbol('age')]); // 30
  • Map 的键
const map = new Map();
map.set(Symbol('key1'), 'value1');
map.set(Symbol('key2'), 'value2');

console.log(map.get(Symbol('key1'))); // value1
console.log(map.get(Symbol('key2'))); // value2
  • Set 的值
const set = new Set();
set.add(Symbol('value1'));
set.add(Symbol('value2'));

console.log(set.has(Symbol('value1'))); // true
console.log(set.has(Symbol('value2'))); // true

避免使用字符串作为属性名

在 ES5 之前,对象的属性名大多都是字符串,这很容易导致属性名重复和冲突。而且,有时我们需要将一些数据保存在对象中,但又不想让这些数据出现在对象的公共接口中。此时,可以使用 Symbol 来创建私有属性。

const person = {
  name: 'John',
  [Symbol('age')]: 30,
};

console.log(person.age); // undefined
console.log(person[Symbol('age')]); // 30

在这个例子中,age 属性是使用 Symbol 创建的,因此它不会出现在 person 对象的公共接口中。只有知道 Symbol 值的人才能访问这个属性。

确保数据的私有性和安全性

Symbol 属性不会出现在 for-in 循环和 Object.keys() 方法的返回结果中,这确保了数据的私有性和安全性。

const person = {
  name: 'John',
  [Symbol('age')]: 30,
};

for (const key in person) {
  console.log(key); // name
}

console.log(Object.keys(person)); // ['name']

在这个例子中,age 属性不会出现在 for-in 循环和 Object.keys() 方法的返回结果中,这确保了 age 属性是私有的。只有知道 Symbol 值的人才能访问这个属性。