一、Symbol数据类型
ES6引入一种新的原始数据类型Symbol,Symbol表示独一无二的值。
注意:js数据类型有八种。
基本类型(单类型):除Object。String、Number、Boolean、Null、Undefined。
引用类型:Object。里面包含function、Array、Date。
在ES5的时候,我们认知的数据类型是6种,Number、Null、Undefined、Boolean、String、Object。
ES6中新增一种Symbol,这种类型的对象永不相等,即使创建的时候传入相同的值,可以解决属性名冲突的问题,作为标记。
谷歌还出现一种bigint。是指安全存储、操作大整数。(很多人不把这个作为数据类型)。
那么,js数据类型有:Number、Null、Undefined、Boolean、String、Object、Symbol、bigInt。
其中:Object中包含了Date、function、Array等,这三种常用的。
二、Symbol特性
1、Symbol的值是唯一的,通常用来解决命名冲突问题
Symbol函数可以接收字符串作为参数,但是即使相同参数返回的也是唯一值。
即使是长得一模一样,也是不一样的两个东西
即使是用同一个变量生成的值也不相等
例:Symbol(‘name’) != Symbol(‘name’)
2、Symbol()函数会返回Symbol类型的值,他不支持实例化对象(new Symbol())
注意:由于Symbol是一个原始类型的值,会返回一个属于自己的类型Symbol,而不是string、object之类的,所以Symbol函数钱不能使用new命令,否则会产生TypeError的报错。
let symbolname = Symbol('symbolName')
console.log(typeof symbolname); // symbol
3、Symbol另一特点就是隐藏性,for…in/object.keys()不能访问
如下图是可以访问的
如下不可以访问
但是也有能够访问的方法:Obj.getOwnPropertySymbols ,这个方法会返回一个数组,包含给定对象所有自有的Symbol值的属性(包括不可枚举的Symbol值属性)。
语法:
Object.getOwnPropertySymbol(obj);
参数
obj:要获取自有Symbol值属性的对象
返回值
一个包含给定对象所有自有的Symbol值得属性的数组。
所有的对象在初始化时都不会包含任何的Symbol值属性,除非在对象上显示定义了Symbol值属性,否则该方法会返回一个空数组。
var a = Symbol('a');
var b = Symbol('b');
var obj = {};
obj[a] = 1;
obj[b] = 2;
Object.getOwnPropertySymbols(obj); // [Symbol(a), Symbol(b)]
var c = Symbol('c');
Object.defineProperty(obj, c, {
value: 3,
enumerate: false,
writable: false,
configuration: false
});
Object.getOwnPropertySymbols(obj); // [Symbol(a), Symbol(b), Symbol(c)]
如果希望能够多次使用同一个Symbol值的情况,有以下两种方法:
①全局注册并登记的方法Symbol.for()
语法:
Symbol.for(key)
参数
key:一个字符串,作为symbol注册表中与某symbol关联的键(同时也会作为该symbol的描述)
返回值
返回由给定的key找到的symbol,否则就是返回新创建的symbol
和Symbol()不同的是,用Symbol.for()方法创建的symbol会被放入一个全局symbol注册表中。Symbol.for()并不是每次都会创建一个新的symbol,它会首先检查给定的key是否已经在注册表中了,假如是,则会直接返回上次存储的那个,否则,他会再新建一个。
let name1=Symbol.for('name');
let name2=Symbol.for('name');
console.log(name1===name2); //true
②Symbol.keyFor():通过symbol对象获取到参数值
语法
Symbol.keyFor(sym)
参数
sym:必选参数,需要查找键值的某个Symbol
返回值:
如果全局注册表中查找到该symbol,则返回改symbol的key值,返回值为字符串类型。否则返回undefined。
var globalSym = Symbol.for("foo");
Symbol.keyFor(globalSym); // "foo"
var localSym = Symbol();
Symbol.keyFor(localSym); // undefined
let name1 = Symbol.for('name');
let name2 = Symbol.for('name');
console.log(Symbol.keyFor(name1)); // 'name'
console.log(Symbol.keyFor(name2)); // 'name'
console.log(Symbol.keyFor(name1)===Symbol.keyFor(name2)); // true
三、使用
使用Symbol替代常量(防止对象属性名称冲突)
//声明方法
let mySymbol=Symbol();
//第一种写法
let a={};
a[mySymbol]='hello';
//第二种
let a={
[mySymbol]:'hello'
};
//第三种
let a={};
Object.defineProperty(a,mySymbol,{value:'hello'});
//上面的写法都得到同样的结果
console.log(a); //{Symbol(): 'hello'}
console.log(a[mySymbol]); //hello