Symbol 是新增的基本数据类型 , 而且是一个值类型.
使用须知:
1. 使用Symbol函数执行得到一个 Symbol 数据类型;
2. Symbol跟字符串差不多,但是 每一个使用Symbol函数执行得到一个数据都是完全不同的 ;
3. Symbol( )接受一个参数 来描述 Symbol的数据 ;
4. Symbol只能转换为字符串和 布尔 类型
let s1= Symbol('123'); //123只是对Symbol的描述 let s2 = Symbol(123); let s3 =Symbol.for(456); let s4 = Symbol.for(456); let obj ={ [s1]:123, a:456 } console.log(obj[s1]) // 123 可以取出值 for(var key in obj){ //symbol类型遍历不出 console.log(key) //a } console.log(Symbol.keyFor(s1) ) //undefined //必须是Symbol.for()创建出的才会被获取到 console.log(Symbol.keyFor(s3)) //456 console.log( s1 == s2) // false console.log(s3 == s4) //true
Symbol.for() 会去找相同参数的 Symbol的值 ,如果没有则会创建一个Symbol
Symbol.keyFor(Symbol) 得到Symbol.for(parmas) 中的 参数 parmas
使用场景
一般当做对象的属性 , 当需要再次添加的对象属性时 ,对象属性避免被覆盖 可以使用Symbol
WeakMap
1. WeakMap 只接受( 除null以外 ) 的对象作为键名
2. WeakMap 的键名所引用的对象是弱引用
3. WeakMap
只有四个方法可用:get()
、set()
、has()
、delete()
。
补充: 弱引用 指 一个对象若只被弱引用所引用,则被认为是不可访问(或弱可访问)的,并因此可能在任何时刻被垃圾回收器回收。
强引用例子:
var obj = new Object();//不会被回收 obj = null; // 只有手动赋值null 才会回收
解决的问题:
WeakMap 可以帮你省掉手动删除对象关联数据的步骤,所以当你不能或者不想控制关联数据的生命周期时就可以考虑使用 WeakMap。
例子 一:
当节点被删除时, 绑定在节点上的数据并不会 被清空 ,必须手动执行 .removeData() 方法才能删除掉相关联的数据,
WeakMap 就可以简化这一操作 :
var el = document.getElementById('el'); console.log(el); const WM3 = new WeakMap(); WM3.set(el,'我是节点需要绑定的相关ID信息'); //设置节点绑定的相关信息 console.log(WM3.get(el)) //可以直接获取节点绑定的相关信息 //当不需要节点时 el.parentNode.removeChild(el); el = null ; console.log(WM3.get(el)) //undefined
例子二 :
设置私有变量
WM5 是实例的弱引用,所以如果删除实例,它们也就随之消失,不会造成内存泄漏。
//设置私有变量 const WM5 = new WeakMap(); class Person{ constructor(name , age){ WM5.set(this,{name:name,age:age}); } getName(){ return WM5.get(this).name; } getAge(){ return WM5.get(this).age; } } var son = new Person('jack',18); console.log(son.getAge(),son.getName()) //18 jack
例子三:
不修改原有对象的情况下储存某些属性或者根据对象储存一些计算的值等,而又不想管理这些数据的死活时非常适合考虑使用
const WM4 = new WeakMap(); let obj2 = { a :1, b:2, c:3 } function countOwnkeys(obj){ if(WM4.has(obj)){ console.log('Cache') return WM4.get(obj); }else{ console.log('compute'); const count = Object.keys(obj).length; WM4.set(obj,count); return count; } } console.log(countOwnkeys(obj2)) ;