1、什么是Symbol
Symbol是es6中一种新增加的数据类型,它表示独一无二的值。es5中我们把数据类型分为基本数据类型(字符串、数字、布尔、undefined、null)和引用数据类型(Object), 在es6中新增的Symbol数据类型划分到基本数据类型
为什么会出现这样一种数据类型?
由于对象的属性和方法是字符串组成,这样新增方法和属性的时候有可能冲突,比如:存在这样一个对象
let obj = {
name: "dog",
say(){
console.log("汪,汪,汪")
}
};
拿到这个对象,给这个对象添加属性或者方法时,可能会添加一个name属性和say方法,如下:
obj.name = "cat";
obj.say = function(){
console.log("喵,喵,喵")
}
console.log(obj.name); // cat
obj.say(); // 喵,喵,喵
这时候,name属性和say方法就被覆盖了,此时我们可以通过Symbol来创建一个独一无二的值
2、如何声明Symbol
1、Symbol是一种基本数据类型,不能new
2、Symbol不能做任何的运算
// 1、Symbol()函数声明
let s1 = Symbol()
let s2 = Symbol()
console.log(s1 === s2) //false 说明创建出来的s1和s2 并不是相同的
console.log(s1, s2); //Symbol() Symbol()
// Symbol(param) Symbol()函数传入参数声明
// 传入的参数就是对当前Symbol的描述,用来区分Symbol
// Symbol里面的参数仅仅是对Symbol的描述,没有其他意义,因此,即使描述相同,Symbol也是不同的
let s1 = Symbol("s1")
let s2 = Symbol("s2")
console.log(s1, s2); //Symbol(s1) Symbol(s2)
3、应用场景
Symbol通常用于设置对象的属性名或者方法,防止新加入的属性或者方法与原来属性或者方法冲突
let obj = {
name: "dog",
say(){
console.log("汪,汪,汪")
}
};
let name = Symbol("name");
let say = Symbol("say");
// 这里必须用[],表示这是一个变量
obj[name] = "cat";
obj[say] = function(){
console.log("喵,喵,喵");
};
console.log(obj);
console.log(obj[name]);// cat
obj[say]();// 喵,喵,喵
4、Symbol不能被for in循环遍历
let obj = {
name: "dog",
say(){
console.log("汪,汪,汪")
}
};
let name = Symbol("name");
let say = Symbol("say");
// 这里必须用[],表示这是一个变量
obj[name] = "cat";
obj[say] = function(){
console.log("喵,喵,喵");
};
for(let [key, value] of Object.entries(obj)){
console.log(key, value);
}
// 输出:
// name dog
// say ƒ say(){
// console.log("汪,汪,汪")
// }
// 可以使用Object.getOwnPropertySymbols查看对象上所有的symbol属性
console.log(Object.getOwnPropertySymbols(obj))
5、symbol.for和symbol.keyFor
Symbol.for可以使用相同的Symbol的值,它接受一个字符串作为参数,然后搜索有没有以该参数作为名称的 Symbol 值。如果有,就返回这个 Symbol 值,否则就新建并返回一个以该字符串为名称的 Symbol 值。
let s1 = Symbol.for('foo');
let s2 = Symbol.for('foo');
s1 === s2 // true
// Symbol.keyFor方法返回一个已登记的 Symbol 类型值的key。
let s1 = Symbol.for("foo");
Symbol.keyFor(s1) // "foo"
let s2 = Symbol("foo");
Symbol.keyFor(s2) // undefined