Skip to content

Symbol

Symbol用于防止属性名冲突而产生的,比如向第三方对象中添加属性时。

Symbol 的值是唯一的,独一无二的不会重复的。

可以简单的理解为symbol就是一个不可能重复的字符串。

基础知识

Symbol

javascript
let v1 = Symbol();
let v2 = Symbol();
console.log(v1); //symbol
console.log(v1 == v2); //false

Symbol 不可以添加属性

javascript
let v1 = Symbol();
v1.name = "后盾人";
console.log(v1.name);

描述参数

可传入字符串用于描述Symbol,方便在控制台分辨Symbol

javascript
let v1 = Symbol("v1");
let v2 = Symbol("v2");

console.log(v1); //Symbol(v1)
console.log(v2.toString()); //Symbol(v2)

传入相同参数Symbol也是独立唯一的,因为参数只是描述而已,但使用 Symbol.for则不会

js
let v1 = Symbol("des")
let v2 = Symbol("des")
console.log(v1 == v2) //false

使用description可以获取传入的描述参数

js
let v1 = Symbol("des")
console.log(v1.description);

Symbol.for

根据描述获取Symbol,如果不存在则新建一个Symbol

  • 使用Symbol.for会在系统中将Symbol登记
  • 使用Symbol则不会登记
js
let v1 = Symbol.for("for")
let v2 = Symbol.for("后for盾人")
console.log(v1 == v2) //true

Symbol.keyFor

Symbol.keyFor 根据使用Symbol.for登记的Symbol返回描述,如果找不到返回undefined 。

js
let v1 = Symbol.for("for")
console.log(Symbol.keyFor(v1))
let v2 = Symbol("for")
console.log(Symbol.keyFor(v2))

对象属性

Symbol 是独一无二的所以可以保证对象属性的唯一。

  • Symbol 声明和访问是使用 [](变量)形式操作
  • 也不能使用 . 语法因为 .语法是操作字符串属性的。

下面写法是错误的,会将symbol 当成字符串symbol处理

js
let v1 = Symbol.for("for")
let obj = {
		v1: "for's value"
}
console.log(obj);
console.log(obj[v1]); //undefined

obj = {
    [v1]: "symbol's value"
}

console.log(obj[v1])

遍历属性

Symbol 不能使用 for/infor/of 遍历操作,使用 Object.getOwnPropertySymbols 获取所有Symbol属性。也可以使用 Reflect.ownKeys(obj) 获取所有属性包括Symbol

javascript
let v1 = Symbol.for("for")
let obj = {
    v1: "for's value",
    [v1]: "for's value"
}

for (const key of Object.getOwnPropertySymbols(obj)) {
    console.log(key) // Symbol(for)
}

for (const key of Reflect.ownKeys(obj)) {
    console.log(key) //v1, Symbol(for) 
}

如果对象属性不想被遍历,可以使用Symbol作为键值进行保护。