前话
ES6引入的第6种基本数据类型:Symbol(符号) 符号可以像字符串那样可以对象的属性名,只是它有唯一性的特点,可以避免属性名之间的冲突 符号没有字面量的形式,只能通过Symbol()函数创建 Symbol()不是构造函数,不能和new运算符组合使用
Symbol初体验
var sym1 = Symbol ( ) ,
sym2 = Symbol ( 'name' ) ,
sym3 = Symbol ( 'name' )
console. log ( sym2 === sym3)
使用typeof运算符识别一个变量是否为符号
let sym1 = Symbol ( 'name' )
let sym2 = Symbol ( 'name' )
console. log ( typeof sym1)
console. log ( typeof sym2)
符号的类型转换
1.符号无法与数字或字符串进行运算 2.符号无法显式的转成数字
let sym = Symbol ( 'name' )
let sym = Symbol ( 'name' )
console. log ( Boolean ( sym) )
console. log ( ! sym)
console. log ( sym. toString ( ) )
console. log ( String ( sym) )
符号的全局共享
ES6会在内部维护一张全局符号注册表,通过Symbol.for()方法,可以登记指定的符号,使其变成一个全局有效的符号,从而达到全局共享
let sym1 = Symbol. for ( 'name' ) ,
sym2 = Symbol. for ( 'name' )
console. log ( sym1 === sym2)
在上述的代码中,在上述的代码中,第一次调用Symbol.for(),会在注册表的中搜索键值为’name’的符号 由于没有找到,所以就会创建一个新的符号 当第二调用Symbol.for(),由于传递的键值与前一次相同,因此会返回刚刚的那个符号
获取全局符号所对应的键值(即它的描述)
let sym1 = Symbol. for ( 'name' ) ,
sym2 = Symbol. for ( 'name' )
console. log ( Symbol. keyFor ( sym1) )
console. log ( Symbol. keyFor ( sym2) )
对象的属性名使用符号表示
方式一
var sym1 = Symbol ( 'name' ) ,
sym2 = Symbol ( 'age' ) ,
obj = { }
obj[ sym1] = 'zsy'
obj[ sym2] = 21
obj. sym1 = 'zsy'
console. log ( obj)
方式二
var sym = Symbol ( 'name' )
let obj = {
[ sym] : 'zsy'
}
console. log ( obj)
方式三
let sym1 = Symbol ( 'name' )
let obj = {
[ sym1] : 'peiqi'
}
Object. defineProperty ( obj, sym1, {
value : 'zsy'
} )
console. log ( obj)
获取对象对象中的符号属性
符号属性是不可枚举的 因此不能被for-in循环到,不能被Object.key(), Object.getOwnPropertyNames()方法读取到 但是可以通过 Object.getOwnPropertySymbols() 方法获取对象的符号属性
let sym = Symbol ( 'name' )
let obj = {
[ sym] : 'zsy' ,
age : 21
}
console. log ( Object. keys ( obj) )
console. log ( Object. getOwnPropertyNames ( obj) )
console. log ( Object. getOwnPropertySymbols ( obj) )
内置符号
ES6提供了内置符号(知名符号) 它们暴露了语言的内部逻辑,允许我们修改或拓展
属性名称 描述 hasInstance 当使用instanceof运算符,该方法会被调用 isConcatSpreadable 当对象作为Array.prototype.concat()方法的参数时,控制该对象是否被展开 match 当对象作为Array.prototype.,match()方法的参数时,该方法会被调用 toStringTag 指定对象的类型,可在调用Object.prototype.toString()方法时返回
hasInstance
let digit = {
[ Symbol. hasInstance] ( number ) {
return ! ( number % 2 )
}
}
console. log ( 1 instanceof digit )
console. log ( 2 instanceof digit )
isConcatSpreadable
let arr1 = [ 3 , 4 ] ;
let res = [ 1 , 2 ] . concat ( arr1)
console. log ( res)
let arr2 = [ 10 , 20 ]
arr2[ Symbol. isConcatSpreadable] = false ;
let res2 = [ 1 , 2 ] . concat ( arr2)
console. log ( res2)
match
let regex = {
[ Symbol. match] ( str ) {
return str. substr ( 0 , 10 )
}
}
let message = 'my name is zsy'
console. log ( message. match ( regex) )
toStringTag
let people = {
[ Symbol. toStringTag] : 'People'
}
console. log ( people. toString ( ) )