创建Symbol并区分方法Symbol是原来的值,所以调用newSymbol会导致程序报错letfirstName=Symbol()letperson={}person[firstName]="angela"console.log(person[firstName])使用typeof来标识其类型letsymbol=Symbol('thisistestdescription')console.log(typeofsymbol)//symbolSymbol可以用来计算对象字面量属性名,Object.defineProperty,Object.defineProperties如果你想要创建共享符号,可以使用Symbol.for方法letuid=Symbol.for('uid')letobject={[uid]:'12345'}console.log(object[uid])//12345console.log(uid)//Symbol(uid)letuid2=Symbol.for('uid')console.log(uid===uid2)//trueconsole.log(object[uid2])//12345console.log(uid2)//符号(uid)符号。keyFor方法获取Symbol全局注册表中Symbol相关的keyletuid=Symbol.for('uid')console.log(Symbol.keyFor(uid))//uidletuid2=Symbol.for('uid')console.log(Symbol.keyFor(uid2))//uidletuid3=Symbol('uid')console.log(Symbol.keyFor(uid3))//undefinedSymbolglobalregistry是类似于globalscope的共享环境,即假设您不能假设当前环境中存在哪些密钥。Symbol和类型强制不能将Symbol强制转换成数值类型,Symbol不能转换成字符串letuid=Symbol.for('uid')letdesc=uid+""//错误UncaughtTypeError:CannotconvertaSymbolvaluetoastringletuid=Symbol.for('uid')letdesc=uid/1//UncaughtTypeError:CannotconvertaSymbolvaluetoanumber但你可以使用letuid如下=Symbol.for('uid')letdesc=String(uid)console.log(desc)//Symbol(uid)Symbol属性检索Object.getOwnPropertySymbolsletuid=Symbol.for('uid')letobject={[uid]:'12345'}letsymbols=Object.getOwnPropertySymbols(object)Symbol.hasInstanceSymbol.hasInstance只接受一个参数,即要检查的值每个函数都有一个Symbol.hasInstance方法,用于判断对象是否是一个functioninstance,Themethod定义在Function.prototype中,没有定义为可写,不可配置,不可枚举letobj=[]//objinstanceofArray//下面的代码相当于这句话Array[Symbol.hasInstance](obj)//true我们可以通过Object.defineProperty方法重写一个不可写的属性,所以我们实际上可以重写所有内置函数(如Date和Error)函数的默认Symbol.hasInstance属性SpecialNumber(){}Object.defineProperty(SpecialNumber,Symbol.hasInstance,{value:function(v){return(vinstanceofNumber)&&(v>=1&&v<=100)}})vartwo=newNumber(2),零=新数字(0);安慰。log(twoinstanceofSpecialNumber)//trueconsole.log(zeroinstanceofSpecialNumber)//falseSymbol.isConcatSpreadableSymbol.isConcatSpreadable属性值true表示属性值应该作为一个独立的元素添加到数组中letc1=['red','green'],c2=c1.concat(['blue','black'],'yellow')console.log(c2)//["red","green","blue","black","yellow"]为什么上面代码的结果是["red","green","blue","black","yellow"]而不是["red","green",["blue","black"“],“黄色的”]?上面的代码稍微改动一下,结果就会完全不同letcollection={0:'hello',1:'world',2:'demo',3:'test',[Symbol.isConcatSpreadable]:true,length:4}letmsg=['Hi'].concat(collection)console.log(msg)//["Hi","hello","world","demo","test"]Symbol.match,Symbol.replace,Symbol.search,Symbol.splitlethasLenOf10={[Symbol.match](v){returnv.length===10?[v.substring(0,10)]:null},[Symbol.replace](v,replacement){返回v.length===10?替换+v.substring(10):v;},[Symbol.search](v){返回v.length===10?0:-1},[符号.split](v){返回v.length===10?["",""]:[v]}}letmsg1='Helloworld',msg2='HelloJohn';console.log(msg1.match(hasLenOf10))//nullconsole.log(msg2.match(hasLenOf10))//[HelloJohn]console.log(msg1.replace(hasLenOf10))//Helloworldconsole.log(msg2.replace(hasLenOf10))//undefinedconsole.log(msg1.search(hasLenOf10))//-1console.log(msg2.search(hasLenOf10))//0console.log(msg1.split(hasLenOf10))//["你好world"]console.log(msg2.split(hasLenOf10))//["",""]Symbol.toPrimitive在执行特定操作时,往往会尝试将对象转换为对应的原始值。Symbol.toPrimitive定义在每个标准类型的原型上,它指定了当对象被转换为原始值时应该执行的操作。每当执行类型转换时,总是会调用Symbol.toPrimitive方法并将值作为参数传入。这个值在规范中称为类型提示提示,类型提示参数只有三个选项number,string,defaultfunctionTemperature(degree){this.degree=degree}Temperature.prototype[Symbol.toPrimitive]=function(hint){switch(hint){case"string":returnthis.degree+'\u00b0';case"number":returnthis.degree;case"default":返回this.degree+"degrees"}}varfreezing=newTemperature(32)console.log(freezing+"!")//32度!console.log(freezing/2)//16console.log(String(freezing))//32°Symbol.toStringTag之前的判断一个对象的类型一般是这样的functionisArray(value){returnObject.prototype.toString.call(value)==="[objectArray]"}在ES6中,我们可以自定义对象字符串标签functionPerson(name){this.name=name}Person.prototype[Symbol.toStringTag]="Person"Person.prototype.toString=function(){returnthis.name}varme=newPerson('angela')console.log(me.toString())//angelaconsole.log(Object.prototype.toString.call(me))//[objectPerson]如果我们不重写toString方法,me.toString返回的值为[objectPerson]我们可以给Person.prototype[Symbol.toStringTag]赋任意值,当然你也可以修改native对象的string标签
