新数据类型 Symbol
声明方式
- Symbol 不是对象,可以理解成不能重复的独立字符串,括号内对象会转化为字符串
- Symbol for 在全局中定义查找,创建多个其实查找是同一个
- Symbol.keyFor 返回已经登记的Symbol类型的key
const obj={
name:'daji',
toString(){
return this.name
}
}
let n=Symbol(obj)
console.log(n); //Symbol(daji)
let c=Symbol([1,2,3])
console.log(c); //Symbol(1,2,3)
let s1=Symbol('foo')
let s2=Symbol('foo')
console.log(s1===s2); //false
let a1=Symbol.for('foo')
let a2=Symbol.for('foo')
console.log(a1===a2); //true
const x1=Symbol('foo')
console.log(Symbol.keyFor(x1)); //undefined
const x2=Symbol.for('foo')
console.log(Symbol.keyFor(x2)); //foo
应用场景
- 对象内如果有重复key值会覆盖的解决方式
const stu1=Symbol('李四')
const stu2=Symbol('李四')
const grade={
[stu1]:{address:'yyy',tel:'111'},
[stu2]:{address:'yyy',tel:'111'}
}
console.log(grade); //{Symbol('李四'):{...},Symbol('李四'):{...}} 不会覆盖,显示两个
console.log(grade[stu1]);
console.log(grade[stu2]);
- 一定程度上保护构造函数的属性
let sym=Symbol('hello')
class User{
constructor(name){
this.name=name
this[sym]='hello.com'
}
getName(){
return this.name+this[sym]
}
}
let user=new User('daji')
console.log(user.getName()); //dajihello.com
for(let key in user){
console.log(key); //name 无法读到Symbol('hello')属性
}
for(let key of Object.keys(user)){
console.log(key); //name 无法读到Symbol('hello')属性
}
for(let key of Object.getOwnPropertyNames(user)){
console.log(key); //name 无法读到Symbol('hello')属性
}
for(let key of Object.getOwnPropertySymbols(user)){
console.log(key); //Symbol(hello) 只能读到symbol属性,读不到name
}
for(let key of Reflect.ownKeys(user)){
console.log(key); //name Symbol(hello) 都能读到
}
- 消除魔术字符串(重复出现的字符串)
const shpeType={
triangle:Symbol(), //triangle:'triangle' vlaue值不重要用symbol替代
circle:Symbol() //circle:'circle'
}
function getArea(shape){
let area = 0
switch(shape){
case shpeType.triangle: //避免case 'triangle' 重复出现此字符串
area=1
break
case shpeType.circle:
area=2
break
}
return area
}
console.log(getArea(shpeType.triangle)); //返回1 避免getArea('triangle') 重复出现此字符串
新数据结构 Set
常用方法
//唯一的 重复的2只会保留1个2
let s=new Set([1,2,3,2])
s.add('es').add('hi') //链式添加
s.delete(2) //删除
s.clear() //清空
console.log(s.has('hi')); //是否包含
console.log(s);
console.log(s.size); //size相当于length
遍历方法
let s1=new Set([1,2,3,2]) //只保留了1个2
console.log(s1);
s1.forEach(item=>{
console.log(item); // 1 2 3
})
for(let item of s1){
console.log(item); //1 2 3
}
for(let item of s1.keys()){
console.log(item); //1 2 3
}
for(let item of s1.values()){
console.log(item); //1 2 3
}
for(let item of s1.entries()){
console.log(item); //[1,1] [2,2] [3,3] key和value
}
应用场景
- 数组去重
let arr = [1,2,3,4,2,3]
let s= new Set(arr)
console.log(s); //set(4){1,2,3,4}
- 合并去重
let arr1=[1,2,3,4]
let arr2=[2,3,4,5,6]
let s1=new Set([...arr1,...arr2]) //扩展运算符打散 set(6){1,2,3,4,5,6}
console.log(s1); //set(4) [1,2,3,4,5,6]
console.log([...s1]); //变成数组形式 [1,2,3,4,5,6]
console.log(Array.from(s1)); //变成数组形式 [1,2,3,4,5,6]
- 交集
let s3=new Set(arr1);
let s4=new Set(arr2);
let result=new Set(arr1.filter(item=>s4.has(item)));
console.log(result); //set(4) {2,3,4}
- 差集 (两数组合并后除去交集)
let result1=new Set(arr1.filter(item=>!s4.has(item)));
let result2=new Set(arr2.filter(item=>!s3.has(item)));
console.log(result1); //set{1}
console.log(result2); //set{5,6}
console.log([...result1,...result2]); //[1,5,6]
- WeakSet (只能存储对象)
let ws =new WeakSet()
const obj1={a:1}
const obj2={b:2}
ws.add(obj1)
ws.add(obj2)
ws.delete(obj1)
console.log(ws);
console.log(ws.has(obj2));
//WeakSet 不能遍历
ws.forEach(item=>{console.log(item);})
//WeakSet 是弱引用,不进入垃圾回收机制(值被引用一次+1)不存在回收问题,适合临时存放一些对象
新数据结构 Map
常用方法
//Map键值对的方式,但key可以为对象
let m=new Map()
let obj={
name:'daji'
}
m.set(obj,'es') //设置 对象做为key,value值对应es
console.log(m);
console.log(m.get(obj)); //获取 es
m.delete(obj)
console.log(m); //删除 空
console.log(m.has(obj)); //false
//这样设置key和value也行
let map=new Map([
['name','daji'],
['age',5]
])
console.log(map);
console.log(map.size);
console.log(map.has('name')); //true
console.log(map.has('age')); //true
map.set('name','zhangsan')
console.log(map); //name的value被覆盖为zhangsan
遍历方法
let map=new Map([
['name','daji'],
['age',5]
])
//第一个参数是value,第二个参数是key
map.forEach((value,key) => {
console.log(value,key);
});
//第一个参数是key,第二个参数是value
for(let [key,value] of map){
console.log(key,value);
}
for(let key of map.keys()){
console.log(key);
}
for(let value of map.values()){
console.log(value);
}
for(let [key,value] of map.entries()){
console.log(key,value);
}
应用场景
- Object对象的应用场景都能使用Map,且Map对键值对的增删改查性能更好
- WeakMap(键名只支持引用数据类型,例如对象数组function)
let wm=new WeakMap()
wm.set([1],2)
wm.set({
name:'daji'
},'es')
console.log(wm);
// wm.clear() //报错不支持clear方法
// wm.size() //报错不支持size方法 wm也不支持遍历
//弱引用 引用次数不会增加 若当前h1dom元素被删除,垃圾机制也不会回收,会自动消失,有助于防止内存泄漏
let wm1=new WeakMap()
let elem=document.getElementsByTagName('h1')
wm1.set(elem,'info')
console.log(wm1.get(elem));
网友评论