最近初看react源码时,看见了symbol一脸懵,虽然知道有这个东西,但是不知道是用来做什么的。 于是决定好好搞明白,就有了这篇文章。
1. symbol是什么
symbol是一种基本数据类型,于ES6引入,用于表示唯一且不可变的值
2. 创建symbol
有两种主要方式创建Symbol
Symbol(description):
创建一个新的 Symbol,并可以提供一个可选的描述字符串
const v1=Symbol('111')
console.log(v1);//Symbol(111)
Symbol.for(key):
在全局注册表中查找或创建一个 Symbol。
如果全局注册表中已经存在与 key 对应的 Symbol,则返回该 Symbol;否则,创建一个新的 Symbol 并注册到全局注册表中。
const v1=Symbol.for('111')
console.log(v1);//Symbol(111)
3. Symbol的特性
唯一性
每次调用Symbol(),都会生成一个唯一的值,即使单位相同
const v1=Symbol('111')
const v2=Symbol('111')
console.log(v1===v2);//false
不可变性
Symbol一旦创建,就无法被修改
let v1=Symbol('111')
console.log(v1.description);//111
v1=Symbol('112')
console.log(v1.description);//112
v1.description='123'
console.log(v1);//Symbol(112)修改失败,无效
其中Symbol 的描述(description 属性)是只读的,不能被修改
为什么v1被成功改变了?因为v1是一个变量,他只是对symbol值的引用
不会被枚举
Symbol作为对象属性的键时,不会被 for...in、Object.keys() 或 JSON.stringify() 等方法枚举:
const obj={
[Symbol('key')]:'value',
['one']:1,
normalKey:'normalValue',
}
console.log(obj);
//{ one: 1, normalKey: 'normalValue', [Symbol(key)]: 'value' }
console.log(Object.keys(obj));
//[ 'one', 'normalKey' ]
console.log(JSON.stringify(obj));
//{"one":1,"normalKey":"normalValue"}
全局注册表
使用 Symbol.for(key) 创建的 Symbol 会被存储在全局注册表中,可以通过 Symbol.keyFor(symbol) 查找其对应的 key:
const v1=Symbol.for('111')
console.log(Symbol.keyFor(v1));//111
4. Symbol的用途
防止属性名冲突
在大型项目或库中,多个模块可能会向同一个对象添加属性。使用SYmbol作为属性名可以避免命名冲突:
const v1 = {
[Symbol('key')]: '111',
};
const v2 = {
[Symbol('key')]: '222',
};
const a = Object.getOwnPropertySymbols(v1); //[ Symbol(key) ]
const b = Object.getOwnPropertySymbols(v2); //[ Symbol(key) ]
console.log(v1[a[0]]);//111
console.log(v2[b[0]]);//222
Object.getOwnPropertySymbols 是 JavaScript 中的一个方法,用于获取一个对象的所有 Symbol 类型的属性键,以数组形式返回。它是 Object 对象的一个静态方法,专门用来处理对象中使用 Symbol 作为属性键的情况。
定义常量
Symbol 可以用来定义一组唯一的常量,确保它们不会与其他值冲突:
const COLOR_RED = Symbol('red');
const COLOR_GREEN = Symbol('green');
const COLOR_BLUE = Symbol('blue');
function getColorName(color) {
switch (color) {
case COLOR_RED:
return 'Red';
case COLOR_GREEN:
return 'Green';
case COLOR_BLUE:
return 'Blue';
default:
return 'Unknown';
}
}
console.log(getColorName(COLOR_RED)); // 'Red'
目前了解到这么多了,后面可能还会加~