一、Symbol的使用
let firstName = Symbol('first name')
// 可选参数为描述不可用于属性反问便于阅读和调试程序
1.Symbol共享体系
Symbol.for()创建一个可共享的Symbol。它首先在全局Symbol注册表中搜索要创建的Symbol是否存在,存在直接返回不存在则创建。
Symbol.keyFor() 在全局注册表中检索键。
2.Symbol属性检索
es5中Object.keys()和Object.getOwnPropertyNames()不支持Symbol属性,es6增加了Object.getOwnPropertySymbols()检索对象中的Symbol属性
二、通过well-known Symbol暴露内部操作
这个是es6开放了JavaScript中常见的内部操作
1.Symbol.hasInstance
每个函数都有这个方法用于确定对象是否为函数的实例。该方法在Function.prototype中定义,不可写不可配置并且不可枚举。只有通过Object.defineProperty()才可以改写一个不可写属性。
function SpecialNumber(){
}
Object.defineProperty(SpecialNumber,Symbol.hasInstance,{
value:function(v){
return (v instanceof Number) && (v>=1 && v<=100)
}
})
let two = new Number(2)
console.log(two instanceof SpecialNumber) // true
2.Symbol.isConcatSpreadable
该属性是一个布尔值,为true则表示对象有length属性和数字键,数值型属性值会被【独立】添加到concat()调用的结果中。该值设置为false时防止元素在调用concat时被分解。
3.Symbol.match Symbol.replace Symbol.search Symbol.split
这四个Symbol对应正则表达式匹配的几个方法,将语言内建的RegExp对象的原生特性完全外包出来,可以使自定义模式匹配更加可行
4.Symbol.toPrimitive
Symbol.toPrimitive方法被定义在每一个标准类型的原型上,并且规定了当对象被转换为原始值时应执行的操作。执行原始值类型转换时,会调用该方法并且传入一个参数(类型提示hint),默认有三种选择:number,string,default。
对于数字模式:
- 调用valueOf()方法,若结果为原始值则返回
- 否则调用toString()方法,若结果为原始值则返回
- 若再无选择值则抛出错误
对于字符串模式:
- 调用toString()方法,若结果为原始值则返回
- 否则调用valueOf()方法,若结果为原始值则返回
- 若再无选择值则抛出错误
【若自定义Symbol.toPrimitive,可以覆盖这些默认的转换特性】
5.Symbol.toStringTag
es6通过Symbol.toStringTag改变了调用Object.prototype.toString()时返回的身份标识。例如对于数组调用Object.prototype.toString.call()返回的值时Array,这个值存储在Symbol.toStringTag属性中
6.Symbol.unscopables
通常用于Array.prototype,以在with语句中标示出不创建绑定的属性名。它是以对象的形式出现,键是在with语句中要忽略的标识符,其对应的值必须为true.
【不要为自己的创建的对象定义这个属性,除非代码中使用了with语句并且正在修改代码库中已有的对象】