如何定义symbol类型(2种方式)
let id1 = Symbol();
console.log(typeof id1);
如果我们将 id 定义为数字类型,当他们id相同时,判断它们是否相等,结果肯定是相等的。
let id1 = 666;
let id2 = 666;
console.log(id1 === id2);// true
但是如果我们将它们定义为symbol类型,那么它们的值是永远不会一样的。
let id1 = Symbol();
let id2 = Symbol();
console.log(id1 === id2);
另外,我们在之前提到了,symbol类型属于基本类型。所以它不是对象,你是不能给它添加属性的。
let id1 = Symbol();
id1.name = "codereasy"; //这样的写法是错误的
那么,有的同学可能会问,在上面的代码当中,如何区分 id1 和 id2 呢?我们声明的时候都是通过 Symbol()
创建的,似乎不太好区分。所以,为了区分两个不同的symbol,我们在创建symbol类型的时候可以给他们加上描述。
let id1 = Symbol("我是1号");
let id2 = Symbol("我是2号");
console.log(id1);
接下来,当我们打印 id1 和 id2 的时候就可以看到它们的描述了。如果你只想看到它的描述内容,可以使用 id1.description.
通过前面的介绍,我们知道每次 Symbol() 都会返回一个新的值,因此 id 1 和 id2的值是不一样的,如果我们想让 id1 === id2 应该如何操作呢?这就引出了定义symbol的第二种方式 symbol.for()
let id1 = Symbol.for("我是1号");
let id2 = Symbol.for("我是1号");
console.log(id1 === id2);
当我们通过symbol.for来定义一个symbol类型之后,如果想要获取它的描述,应该怎么做呢?
let descroption = Symbol.keyFor(id1)
注意,Symbol.keyFor
这种方式只能获取 Symbol.for
定义的变量。普通方式定义的是无法获取的。
应用场景
1.解决id重复的问题
let salary = {
张三: 6000,
张三: 12000,
};
console.log(salary); //张三: 12000
let person1 = {
name: "张三",
key: Symbol(),
};
let person2 = {
name: "张三",
key: Symbol(),
};
let salary = {
[person1.key]: 6000,
[person2.key]: 12000,
};
console.log(salary);
如果我们想看第二个张三的工资
salary[person2.key]
symbol的其他特性
key in 和key of dou不能遍历
let person1 = {
name: "张三",
[Symbol()]: "我是symbol属性",
};
// for (const key in person1) {
// console.log(key);
// }
for (const key of Object.keys(person1)) {
console.log(key);
}
如果我们想遍历symbol,那么需要用以下代码
for (const key of Object.getOwnPropertySymbols(person1)) {
console.log(key);
}
如果我们想要遍历所有属性,需要用Reflect.ownKeys()
let person1 = {
name: "张三",
[Symbol()]: "我是symbol属性",
};
for (const key of Reflect.ownKeys(person1)) {
console.log(key);
}
定义私有属性
let id = Symbol();
class Student {
constructor(name) {
this.name = name;
this[id] = 666;
}
getId() {
return this[id];
}
}
let codereasy = new Student();
console.log(codereasy.getId());
for (const key in codereasy) {
console.log(key);
}