Symbol 是原始数据类型,创建之后会在栈内存中存在,并不会向引用数据类型一样在堆内存中存在。它存在的意义是为了确保对象属性唯一,不会存在属性冲突。在我的理解中,它就是创建了一个内存地址存在栈内存中,类似于引用数据类型的存储。
let a:symbol = Symbol(1);
let b:symbol = Symbol(1);
console.log(a === b); // false
console.log(a == b); // false
在 Symbol() 中,创建一个实例时无论传给 Symbol 的值是否相同都会在内存中新建一个 Symbol 实例。
那有没有办法让两个 Symbol 返回 true 呢?
let a = Symbol.for("1");
let b = Symbol.for("1");
console.log(a === b); // true
Symbol.for():创建一个实例之后就会在 Window 中存在,也就类似于全局变量。b在此时会从全局中找是否存在 Symbol.for() 相同的实例,有的话就会返回原来的值,不存在的话就会新开辟一个内存空间。所以这时 a === b 就为 true
比如一个班级中有同学重名,此时Symbol就出现了它的应用场景
let a = Symbol("李四");
let b = Symbol("李四");
let obj = {
[a]: 80,
[b]: 100
}
console.log(obj); // { [Symbol(李四)]: 80, [Symbol(李四)]: 100 }
Symbol() 遍历
let a = Symbol(1);
let obj = {
name: "test",
[a]: 80
}
for (const key in obj) {
console.log(key); // 输出 name
}
console.log(Object.keys(obj)); // ['name'] 无法读到 Symbol
console.log(Object.getOwnPropertyNames(obj)); // ['name'] 无法读到 Symbol
console.log(Object.getOwnPropertySymbols(obj)); // [Symbol(1)] 无法读到 Symbol 外的属性
console.log(Reflect.ownKeys(obj)); // ['name', Symbol(1)] 既可以读到 Symbol,也可以读到其他属性