ES6 Set WeakSet Map WeakMap 生成器函数 yield

前言

数组和对象的区别:
数组的优点:有顺序、紧密性、有关联
数组的缺点:增删改查速度慢、有重复、判断值时必须要遍历数组
对象的优点:有键值对,增删改查速度快、键唯一、多重集合
对象的缺点:没有关联、顺序无法改变(按照添加的顺序遍历)、如果需要查询属性时,需要进行遍历

Set 对象

Set 对象是一个列表,插入、添加、删除速度快,没有重复,只有值(没有键),没有索引,不能使用 for 循环,也不能用下标直接修改或者获取。

Set结构是键名和键值是同一个值。

  • size,获取 Set 的长度
  • add(),添加,如果有相同值,不添加;不同类型的值也可以添加;对象的引用地址不同,所以即使值相同,也可以添加
  • delete(),删除 Set 中的指定值,删除成功返回 true,删除失败返回 false
  • has(),判断值是否存在,存在的话返回 true,不存在返回 false
  • clear(),清除 Set 中的所有数据
  • entries(),返回一个键值对的遍历器
var a=new Set([1,2,3,4,5]);
console.log(a);//Set(5) [ 1, 2, 3, 4, 5 ]

//用size来获取set的长度
console.log(a.size);//5

a.add(6);//[1,2,3,4,5,6] 添加值
a.add(4);//[1,2,3,4,5,6] 如果有相同值,不添加
a.add("text");//[1,2,3,4,5,6,"text"]
var s={a:1,b:2};
a.add(s);
a.add({a:1,b:2});//[1,2,3,4,5,6,"text",{...},{...}]
//因为对象之间引用地址不同,所以即使值相同,也可以存储

a.delete(4);//[1,2,3,5,6,"text",{...},{...}]
a.has(3);//true
a.clear();//[]

用 forEach 遍历 Set 时,键和值是完全相同的

var a=new Set([1,2,3,4,5]);
a.forEach(function(index,value,a){
   // 遍历键和值完全相同
    console.log(index,value,a);
})
//打印出的结果如下:
1 1 Set(5) [ 1, 2, 3, 4, 5 ]
2 2 Set(5) [ 1, 2, 3, 4, 5 ]
3 3 Set(5) [ 1, 2, 3, 4, 5 ]
4 4 Set(5) [ 1, 2, 3, 4, 5 ]
5 5 Set(5) [ 1, 2, 3, 4, 5 ]

for of 对 iterable 接口的数据进行遍历
注意:for of 只能遍历 Set 和 Map

var a=new Set([1,2,3,4,5]);
for(let value of a){
   console.log(value);//1 2 3 4 5
}

entries 返回遍历器对象的 value 属性值是一个具有两个相同元素的数组,数组元素值是Set对象的元素值,也就是说Set结构是键名和键值是同一个值。

var a=new Set([1,2,3,4,5]);
console.log(a.entries());
for(let value of a.entries()){
	console.log(value);
}

上面打印的代码如下:
Set entries

Set 数据的类型转换

Array 转 Set,将数组直接代入 Set 中
Set 转 Array,用 … 操作符,也可以直接用 Array.from()
String 转 Set,将字符串直接代入 Set 中
Set 中 toString 方法是不能将 Set 转换成 String

var arr=[1,3,2,4,5,2,1,2,3,5,3,2,3,5,2,1];
//将数组转成Set
var set=new Set(arr);//Set(5) [ 1, 3, 2, 4, 5 ]
//用...操作符,将Set转Array
var arr1=[...set];//Array(5) [ 1, 3, 2, 4, 5 ]
//String 转 Set
var set1=new Set("hello");//["h","e","l","o"]

因为 Set 值的唯一性,Set 可以用来数组去重

var arr=[1,3,2,4,5,2,1,2,3,5,3,2,3,5,2,1];
arr=Array.from(new Set(arr));
console.log(arr);//[1,2,3,4,5]

Map对象

Map 对象保存键值对。任何值(对象或者原始值) 都可以作为一个键或一个值。
Map 需要有键值对,需要有长度,可以遍历属性列表,可以遍历数值列表,增删改查速度快

  • size,获取Map的长度
  • set(),添加键值对
  • get(),获取值
  • has(),判断 Map 里有没有对应的值,有的话返回true,没有返回false
  • delete(),删除指定向
  • clear(),清除 Map
let a=new Map();
a.set("name","xiaoming");
a.set("age",30);
a.set("sex","man");//添加键值对
console.log(a.size);//3
console.log(a.get("age"));//30
console.log(a.has("age"));//true 只能用来查找键
a.delete("age");//删除键值对
a.clear();//清空

使用 forEach 对 Map 的遍历

let a=new Map();
a.set("name","xiaoming");
a.set("age",30);
a.set("sex","man");

a.forEach(function(value,key,a){
	console.log(value,key,a);
})
//打印结果如下:
xiaoming name 
Map(3) { name → "xiaoming", age → 30, sex → "man" }

30 age 
Map(3) { name → "xiaoming", age → 30, sex → "man" }

man sex 
Map(3) { name → "xiaoming", age → 30, sex → "man" }

使用 for of 对 Map 的遍历,可以只遍历 Map 的 key 或者只遍历Map的 value

for(let arr of a){
//相等于for(let arr of a.entries()){}
	console.log(arr);
}
//打印结果如下(第0项是键,第1项是值):
Array [ "name", "xiaoming" ]
Array [ "age", 30 ]
Array [ "sex", "man" ]

//只对Map的key进行遍历
for(let key of a.keys()){
	console.log(key);//name age sex
}

//只对Map的value进行遍历
for(let value of a.values()){
	console.log(value);//xiaoming 30 man
}

扩展

WeakSet

WeakSet 结构同样不会存储重复的值,不同的是,它的成员必须是对象类型的值。

以数组来举例,把 obj 对象插入到数组中后,将 obj 设为 null 后,数组里的第一位还是 {a:1}。如果要删除数组里的第一位,需要手动将 arr[0] 设为 null ,再移除数组里的第一位,操作比较繁琐。

var obj={a:1};
var arr=[];
arr.push(obj);
obj=null;
arr[0]=null;
arr.shift();
console.log(arr)

而 WeakSet 是弱引用关系,当将 obj 设为 null 时,被维护的 WeakSet 列表中会自动清除它,将 obj 设为 null 后,WeakSet 列表中会自动清除它,但是需要等垃圾回收车来回收 obj。

var obj={a:1};
var b=new WeakSet();
b.add(obj);
obj=null;
console.log(b);

弱引用列表是不可遍历的

var arr=[
	{a:1,b:2},
	{a:2,b:2},
	{a:3,b:2},
	{a:4,b:2}
]
var a=new WeakSet(arr);
for(let value of a){
	//会直接报错
	console.log(value);
}

WeakMap

普通的map不能使用对象作为属性存储值,WeakMap 弱引用类型,将key设为对象,当对象清除后,弱引用map会自动清除

注意:弱引用的类型不可以遍历

var c=new WeakMap();
var obj={a:10};
c.set(obj,10);
obj=null;
console.log(c);

生成器函数

  • 遇到 yield 会停止不执行,相当于断点
  • 当执行函数返回对象的 next() 方法时才会继续向下执行
  • 或者可以使用for of 自动执行完成一个 yield 后继续向下执行
  • yield 会返回右侧变量的值
function* fn(a,b){
    yield a;
    a++;
    yield a;
    yield b;
    b++;
    yield b;
    yield a+b;
    return a+b;
} 
var a=fn(3,4);
console.log(a.next());//{ value: 3, done: false }
console.log(a.next());//{ value: 4, done: false }
console.log(a.next());//{ value: 4, done: false }
console.log(a.next());//{ value: 5, done: false }
console.log(a.next());//{ value: 9, done: false }
console.log(a.next());//{ value: 9, done: true }

//或者可以用for of 来自动执行完成一个yield后继续向下执行
for(let value of a){
   console.log(value);//3 4 4 5 9
}
发布了50 篇原创文章 · 获赞 27 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/Charissa2017/article/details/103937710