跳到主要内容

Symbol

Symbol

不能使用new命令

Symbol函数前不能使用new命令,否则会报错,也就是说Symbol 是一个原始类型的值,不是对象,也不能添加属性

let s = Symbol();
typeof s // symbol
let s1 = Symbol('a');
let s2 = Symbol('a');

s1 === s2 //false

有toString方法

let s1 = Symbol('a');
let s2 = Symbol('b');

s1.toString() // 'Symbol(a)'
s2.toString() // 'Symbol(b)'

不能进行运算,但可以转为布尔值

let s = Symbol();
s + '2' // Cannot convert a Symbol value to a string
Boolean(s) // true
!s // false

适合用作对象属性名

可以保证不会出现同名的属性,对于一个对象由多个模块构成的情况非常有用,能防止某一个键被不小心改写或覆盖;值得注意的是,Symbol 值作为对象属性名时,不能用点运算符,因为点运算符后面是一个字符串;

let obj  = {
[s] : 'hello world'
}

obj.s // undefined
obj[s] // hello world

Symbol 作为属性名,不会被常规方法遍历得到

模拟实现Set的时候被坑了哈哈,确实不能遍历到

该属性不会出现在for...in、for...of循环中,也不会被Object.keys()、Object.getOwnPropertyNames()、JSON.stringify()返回,但是,它并不是私有属性,可以使用 Object.getOwnPropertySymbols 方法,可以获取指定对象的所有 Symbol 属性名;

var obj = {};
var a = Symbol('a');
var b = Symbol('b');

for( let key in obj ){
console.log(key) // 只有c
}

var objectSymbols = Object.getOwnPropertySymbols(obj);

console.log(objectSymbols) // [Symbol(a), Symbol(b)] 然后变量这个数组去取obj[Symbol(a)]

Symbol.for

接受一个字符串作为参数,然后搜索有没有以该参数作为名称的Symbol值。如果有,就返回这个Symbol值,否则就新建并返回一个以该字符串为名称的Symbol值

Symbol.for("name") === Symbol.for("name")
// true

Symbol("name") === Symbol("name")
// false

Symbol.keyFor

返回一个已登记的 Symbol 类型值的key,而Symbol()写法是没有登记机制的;

var s1 = Symbol.for("name");
Symbol.keyFor(s1) // "name"

var s2 = Symbol("name");
Symbol.keyFor(s2) // undefined