为什么需要Symbol
ES5里面对象的属性名都是字符串,如果你需要使用一个别人提供的对象,你对这个对象有哪些属性也不是很清楚,但又想为这个对象新增一些属性,那么你新增的属性名就很可能和原来的属性名发送冲突,显然我们是不希望这种情况发生的。所以,我们需要确保每个属性名都是独一无二的,这样就可以防止属性名的冲突了。因此,ES6里就引入了Symbol
,用它来产生一个独一无二的值。
Symbol是什么
Symbol
实际上是ES6引入的一种原始数据类型,除了Symbol
,JavaScript还有其他5种数据类型,分别是Undefined
、Null
、Boolean
、String
、Number
、对象,这6种数据类型都是ES5中就有的。
es6新增数据类型 Symbol
(生成独一无二的数据的)
用Symbol
函数生成的原始数据类型不存在引用值地址的说法的也是在内存占据空间的。
怎么生成一个Symbol类型的值
既然我们已经知道了Symbol
是一种原始的数据类型,那么怎么生成这种数据类型的值呢?Symbol
值是通过Symbol
函数生成的,如下:
let s1 = Symbol();//生成Symbol数据类型,结果是symbol()
console.log(s1);
console.log(typeof s1);//检测Symbol数据类型,结果是symbol
被Symbol
生成的数据是独一无二(如下)
let s1 = Symbol();
let s2 = Symbol();
console.log(s1===s2);//false
console.log(Object.is(s1,s2));//false
//即使用Symbol生成的数据完全一样,那么也不是一个东西
//(只要是通过Symbol这个函数生成的Symbol数据本质上就是独一无二的,即使你长的一样但是本质也
//是不一样的)
符号的特点
- 符号没有字面量的写法
- 符号没有字面量的写法
const syb1 = Symbol();
console.log(typeof syb1); //symbol
- 调用Symbol函数得到的符号永远不会相等,不管符号描述是否相同
const syb1 = Symbol("ycxvip");
const syb2 = Symbol("ycxvip");
console.log(syb1 === syb2); //false
- 符号可以作为对象的属性名使用,这种属性名叫符号属性
const syb1 = Symbol("abc");
const obj = {
a: 1,
b: 2,
[syb1]: 3,
}
console.log(obj); // {a: 1, b: 2, Symbol(abc): 3}
- 符号可以通过设计,让外面无法访问到
const syb1 = Symbol("abc");
const obj = {
a: 1,
b: 2,
[syb1]: 3,
}
console.log(obj); // {a: 1, b: 2, Symbol(abc): 3}
- 符号属性不能被枚举
const syb1 = Symbol("abc");
const obj = {
a: 1,
b: 2,
[syb1]: 3,
}
console.log(obj); // {a: 1, b: 2, Symbol(abc): 3}
for (let key in obj) {
console.log(key); // a b
}
console.log(Object.keys(obj)); // ["a", "b"] es5获取属性名的方法获取不到符号属性
console.log(Object.getOwnPropertyNames(obj)); // ["a", "b"] es6获取属性名的方法获取不到符号属性
console.log(Object.getOwnPropertySymbols(obj)); // [Symbol(abc)] es6专门的获取符号属性的方法
- 符号类型无法被隐式转换,数字运算,字符串拼接都是不行的(但是可以进行内部的显示转换)
const syb1 = Symbol("abc");
console.log(syb1 + 123); // TypeError: Cannot convert a Symbol value to a number