,ES6的新特性除了JavaScript中的几种基本数据类型,Number,String,Boolean,Object,null,undefined,ES6还引入了一种新的原始数据类型Symbol,它代表一个唯一的值,属于类字符串数据类型,可用于定义对象的唯一属性名称。基本上使用ES5的对象的属性名都是字符串,很容易造成属性名冲突。ES6中新引入的Symbol类型可以解决这个问题。Symbol值由Symbol函数生成,可用于定义对象的唯一属性名称。属于Symbol类型的属性名都是唯一的,保证不和其他属性名冲突。示例:让sym=Symbol();console.log(sym类型);//输出:symbol在上面的代码中,变量sym是一个唯一的值。使用typeof运算符知道sym是Symbol数据类型。需要注意的是新命令不能在Symbol函数之前使用,否则会报错。因为Symbol是原始数据类型,不是对象。Symbol函数可以接受一个字符串作为参数,为新创建的Symbol提供描述,可以在控制台显示,也可以作为字符串使用,方便区分。示例:letsym1=Symbol(11);letsym2=Symbol('xkd');console.log(sym1);//输出:Symbol(11)console.log(sym2);//输出:Symbol(xkd)console.log(sym1===sym2);//Output:false在上面的代码中,sym1和sym2是两个Symbol值。如果不加参数,它们的输出都是Symbol(),不利于区分。但是同一个参数Symbol()返回的值不相等,我们来看一下:letsym1=Symbol('xkd');letsym2=Symbol('xkd');console.log(sym1===符号2);//输出:falseSymbol不能参与运算Symbol值不能和其他类型的值进行运算,否则会报错。例子:比如下面的代码,如果在Symbol类型的数据sym中加入字符串类型的数据hello,就会报错:letsym=Symbol('xkd');console.log('hello'+sym);//错误提示:TypeError:CannotconvertaSymbolvaluetoastringtypeconversion类型Symbol的值可以转换为字符串或布尔类型的值。示例:将Symbol值显示转换为字符串:letsym=Symbol('xkd');console.log(typeofString(sym));//输出:stringconsole.log(typeofsym.toString());//Output:stringConvertSymbolvaluedisplaytoBooleanvalue:letsymbol=Symbol();console.log(typeofBoolean(symbol));//Output:booleanSymbol.prototype.description可以在创建Symbol的时候添加描述,我们通过description属性可以获取描述内容。该属性是ES2019中的新实例属性。例子:比如在下面的代码中,'你好,侠客岛!'是对sym的描述:constsym=Symbol('你好,侠客岛!');console.log(sym.description);//输出:你好,侠客岛!Symbol作为对象属性名,可以作为对象属性名的标识,保证对象中不会出现同名属性。示例:让sym=Symbol();让obj={};obj[sym]='xkd';console.log(obj);//Output:{[Symbol()]:'xkd'}上面的代码其实有两种写法,第一种写法是:letsym=Symbol();letobj={[sym]:'xkd'};控制台日志(对象);//output:{[Symbol()]:'xkd的第二种写法'}是:letsym=Symbol();letobj={};Object.defineProperty(obj,sym,{value:'xkd'});控制台日志(obj);//output:{[Symbol()]:'xkd'}以上三种写法可以得到相同的结果。当Symbol值用作对象属性名称时,不能使用点运算符。示例:constsym=Symbol();常量对象={};obj.sym='xkd';console.log(obj[sym]);//输出:undefinedconsole.log(obj['sym']);//输出:xkd属性遍历在遍历对象时,Symbol作为属性名不会出现在for...in,for...of循环中,也不会被Object.keys(),Object.getOwnPropertyNames(),JSON.stringify()返回。他们会过滤掉Symbol,但是我们可以通过两种方式获取所有Symbol的属性名。方法一:使用Object.getOwnPropertySymbols方法:constobj={};letsym1=Symbol('111');letsym2=Symbol('222');obj[sym1]='111';obj[sym2]='222';console.log(Object.getOwnPropertySymbols(obj));//输出:[Symbol(111),Symbol(222)]方法二:使用Reflect.ownKeys方法:constobj={};letsym1=Symbol('111');letsym2=Symbol('222');obj[sym1]='111';obj[sym2]='222';console.log(Reflect.ownKeys(obj));//输出:[Symbol(111),Symbol(222)]Symbol.for()方法Symbol.for()方法是唯一可以让两个Symbol相等的方法,在全局环境中寻找下面描述的Symbol,如果找到则返回这个即可Symbol,否则会生成一个新的Symbol,即返回当前索引Symbol。示例:letsymbol1=Symbol.for('xkd');letsymbol2=Symbol.for('xkd');控制台日志(符号1===符号2);//output:trueSymbol.keyFor()方法Symbol.keyFor()方法可以返回注册的Symbol的key。示例:letsyb1=Symbol.for("xkd");console.log(Symbol.keyFor(syb1));//输出:xkdletsyb2=Symbol("xkd");console.log(Symbol.keyFor(syb2));//输出:未定义
