1. Iterator迭代器
上文提到的for...of不能遍历对象的属性,原因是对象的属性是无序的,在设计对象的时候没有加入Iterator迭代器
可迭代的对象有:String、Array、TypedArray、Map 和 Set,这些对象(或者它原型链上的某个对象)必须有一个键为 iterator 的属性
迭代器是可迭代对象(或其原型链上的一个方法),可通过[Symbol.iterator]()
来调用到它;该方法返回一个对象,返回对象的原型上有next()
方法;通过next()
方法来遍历最初的可迭代对象。
next
的返回值是包含value
和done
属性的一个对象;value
是迭代的值,done是迭代的状态
let arr = [‘a‘, ‘b‘, ‘c‘];
let step = arr[Symbol.iterator]();
console.log(step);//Array Iterator {}
console.log(step.next());//{value: "a", done: false}
console.log(step.next());//{value: "b", done: false}
console.log(step.next());//{value: "c", done: false}
console.log(step.next());//{value: undefined, done: true}
1.1 自定义迭代器
给对象添加自定义迭代器,使用for...of访问
let name = ‘zs‘;
let age = 14;
let person1 = {
name, age,
[Symbol.iterator]: function () {
let _this = Object.keys(this);
let index = 0;
return {
next: () => {
let value = {
key: _this[index],
value: this[_this[index]]
}
let done = (index >= _this.length);
index++;
return { value, done }
}
}
}
}
for (let v of person1) {
console.log(v);
}
//Object { key: "name", value: "zs" }
//Object { key: "age", value: 14 }
2. Generator生成器
Generator生成器对象是由一个 generator function 返回的
这个函数的声明如下
function* gen() {
yield 1;
yield 2;
yield 3;
}
let g = gen();//g 就是Generator生成器对象
生成器对象和迭代器对象一样,有一个next方法,用于返回一个由yield
表达式生成的值
g.next(); // "Object { value: 1, done: false }"
g.next(); // "Object { value: 2, done: false }"
g.next(); // "Object { value: 3, done: false }"
g.next(); // "Object { value: undefined, done: true }"
2.1 yield*
如果想在一个Generator函数里调用另一个Generator函数,需要用到yield*
关键字
function* gen2() {
yield ‘start‘
yield* gen();
yield ‘end‘;
}
let g2 = gen2();
3. Set和WeakSet用法
Set
对象允许你存储任何类型的唯一值(除了不可迭代对象以外),无论是原始值或者是对象引用
Set
对象是值的集合,你可以按照插入的顺序迭代它的元素。 Set中的元素只会出现一次,即 Set 中的元素是唯一的
3.1 set去重
let arr1 = [1,2,2,4,6,4]
function removeRepeat(arr) {
return Array.from(new Set(arr));
}
removeRepeat(arr1);//[1, 2, 4, 6]
3.2 size属性
var mySet = new Set([1,2,3]);
console.log(s.size);//3
3.3 方法
- add方法
用来向一个 Set
对象的末尾添加一个指定的值;可以链式调用;
mySet.add(‘abc‘);
console.log(mySet);//Set(4) {1, 2, 3, "abc"}
- clear方法
用来清空一个 Set
对象中的所有元素;mySet.clear();
- delete方法
可以从一个 Set
对象中删除指定的元素;mySet.delete(value);
- has方法
返回一个布尔值来指示对应的值value是否存在Set对象中;mySet.has(value);
- entries、keys、values方法
entries:返回一个新的迭代器对象 ,这个对象的元素是类似 [value, value] 形式的数组
由于set对象不像Map对象那样拥有 key,然而,为了与 Map 对象的 API 形式保持一致;所以set的key和value是相同的值
keys/values:返回一个新的迭代器对象,该对象包含Set
对象中的按插入顺序排列的所有元素的值
let mySet = new Set([1, 2, 3]);
mySet.add(‘abc‘)
console.log(mySet.entries());//SetIterator {1 => 1, 2 => 2, 3 => 3, "abc" => "abc"}
4. Map和WeakMap用法
Map 对象保存键值对,并且能够记住键的原始插入顺序。任何值(对象或者原始值) 都可以作为一个键或一个值。
4.1 size属性
let map1 = new Map([[‘name‘, ‘zs‘],[‘age‘,19]]);
console.log(map1.size);
4.2 方法
- get方法:返回键对应的值,如果不存在,则返回undefined
map1.get(key)
- set方法:添加或更新一个指定键和值。返回该Map对象
map1.set(key, value)
- delete方法:移除map对象中指定的元素;如果
Map
对象中存在该元素,则移除它并返回true
;否则如果该元素不存在则返回false
map1.delete(key)
- clear方法:移除Map对象的所有键值对;返回undifined
map1.clear()
- has方法:表示Map实例是否包含键对应的值,返回一个布尔值,
map1.has(key)
- entries、keys、values方法
entries:返回一个新的包含 [key, value]
对的 Iterator
对象,返回的迭代器的迭代顺序与 Map
对象的插入顺序相同
keys:返回一个新的 Iterator
对象。它包含按照顺序插入 Map
对象中每个元素的key值
values:返回一个新的Iterator对象。它包含按顺序插入Map对象中每个元素的value值
let map2 = new Map();
map1.set(‘0‘, ‘foo‘);
map1.set(1, ‘bar‘);
let iterator1 = map1.entries();
let iterator2 = map1.keys();
let iterator3 = map1.keys();
console.log(iterator1.next().value);// ["0", "foo"]
console.log(iterator1.next().value);// [1, "bar"]
console.log(iterator2.next().value);// "0"
console.log(iterator2.next().value);// 1
console.log(iterator3.next().value);// "foo"
console.log(iterator3.next().value);// "bar"
- map可以使用forEach遍历