Symbol
2019-03-04 21:34 思雯 阅读(306) 评论(0) 收藏 举报一.原因
1.1 从根本上防止属性名的冲突,保证每个属性名称都是独一无二的,
由原来的6种数据结构 undefined null Boolean String Number Object 扩展一个Symbol
let demo1=Symbol() console.log(typeof demo1) //symbol
1.2 注意事项
(1)Symbol前不能使用new 会报错 它是类似字符串的数据类型 无法添加属性
(2)Symbol函数可以接受一个字符串作为参数 主要来描述Symbol实例 在控制台种能够区分
(3)如果参数是对象 就会调用对象的toString方法 生成一个Symbol
(4)即使两个参数相同Symbol的返回值也是不相等的
(5)Symbol值不能与其他值进行运算 会报错 console.log("string"+symbol) 都会报错
(6)可以显式的转成字符串
(7)可以转成布尔值,但不能转为数值(Number(stmbol)//会报错)
(8)不能使用,运算符号取到定义的属性值 (例如xx.mySymbol )
let mySymbol=Symbol(
{
a:10 ,
toString(){
return 'x'
}
}) //Symbol[x] 注意事项(3)
console.log("xxxx"+mySymbol)//Cannot convert a Symbol value to a string
//注意事项(5)
let a={}
let mySymbol=Symbol() a[mySymbol]='hello' console.log(a.mySymbol)//undefined
a.mySymbol='mytest'
console.log(a.mySymbol)//mytest console.log(a[mySymbol])//hello
二.作为属性名的symbol基础用法
let a={} let mySymbol=Symbol();a[mySymbol]='hello' //第一种 let a={ [mySymbol]:'hello'}//第二种 Object.defineProperty(a,mySymbol,{value:'hello'})//第三种
三 如何取值
3.1 不会出现在for...in,for...of循环种也不会Object.keys()、Object.getOwnPropertyNames()、JSON.stringify()返回
3.2 同时也不是私有属性(Object.getOwnPropertyNames(obj)获取不到),有一个Object.getOwnPropertySymbols方法,可以获取指定对象的所有 Symbol 属性名。
3.3 Reflect.ownKeys(obj4) 可以获取obj4种的所有symbol值(数组)
3.4 由于以 Symbol 值作为名称的属性,不会被常规方法遍历得到。我们可以利用这个特性,为对象定义一些非私有的、但又希望只用于内部的方法。
let obj4={} let a4=Symbol('a') let b4=Symbol('b') obj4.c='c' obj4[a4]='hello'; obj4[b4]='world' let objSymbol4=Object.getOwnPropertySymbols(obj4) //3.2的demo 获取所有Symbol objSymbol4.forEach((item)=>{ console.log(item);//Symbol(a), Symbol(b) }) console.log(Reflect.ownKeys(obj4))//(3) ["c", Symbol(a), Symbol(b)]//获取包含Symbol的所有属性值 3.3的demo
四. Symbol.for(),Symbol.keyFor()
4.1 Symbol() 调用30个会返回30个 都不相同
4.2 Symbol.for() 会生成新的Symbol在全局中 如果存在则不创建,会返回那个 如果不存在则创建 调用30次只会返回一个 都相同
4.3 Symbol.keyFor() 参数是Symbol类型不是key 。返回已登记的 Symbol 类型值的key。 查找 Symbol.for()注册的 而 symbol(' ')的不算是
let temp5=Symbol('temp5')
let temp5_1=Symbol('temp5')
Symbol.keyFor(temp5)//undefined 说明Symbol.keyFor只能查询到到Symbol.for('temp5')这种定义 而查不到普通的Symbol('temp5')
let temp5_2=Symbol.for('temp5')
let temp5_3=Symbol.for('temp5')
Symbol.keyFor(temp5_2)//temp5 4.3的demo
console.log(temp5==temp5_1)//false 4.1的demo
console.log(temp5_1==temp5_2)//false
console.log(temp5==temp5_2)//false
console.log(temp5_2==temp5_3)//true 4.2的demo
五 实例:模块的 Singleton 模式
const FOO_KEY = Symbol.for('foo'); function A()
{ this.foo = 'hello'; } if (!global[FOO_KEY]) { global[FOO_KEY] = new A(); } module.exports = global[FOO_KEY];
六 除了定义自己使用的 Symbol 值以外,ES6 还提供了 11 个内置的 Symbol 值,指向语言内部使用的方法。
6.1 Symbol.hasInstance
class MyClass{ [Symbol.hasInstance](foo){ return foo instanceof Array } } console.log([1,2,3] instanceof new MyClass())//true
6.2Symbol.replace
对象的Symbol.replace属性,指向一个方法,当该对象被String.prototype.replace方法调用时,会返回该方法的返回值
Symbol.replace方法会收到两个参数,第一个参数是replace方法正在作用的对象,上面例子是Hello,第二个参数是替换后的值,上面例子是World。
const x = { [Symbol.replace](...s){ console.log(s) } }; 'Hello'.replace(x, 'World') // ["Hello", "World"]
6.3.Symbol.species
有些类库是在基类的基础上修改的,那么子类使用继承的方法时,作者可能希望返回基类的实例,而不是子类的实例。
class T1 extends Promise { } class T2 extends Promise { static get [Symbol.species]() { return Promise; } } console.log("demo9") console.log(new T1((r=>r())).then(v=>v) instanceof T1)//true console.log(new T2((r=>r())).then(v=>v) instanceof T2)//false
6.4等等
浙公网安备 33010602011771号