-
什么是 for-fo 是一个可迭代对象 迭代对象具有 Symbol.iterator 属性 是一种与迭代器相关的对象
Symbol.iterator 通过指定的函数可以返回一个早哟用与附属对象的迭代器 在ES6中所有的集合 (Set Map 集合)
字符串都是可迭代对象 这些对象都有默认的迭代器 在ES6中的for-of 循环中需要用到迭代对象的一些功能生成器默认都有 Symbol.iterator 属性 因此所有通过生成器创的迭代对像都是可以迭代对象
在for-of 循环每一次都会调用可迭代对象的next() 方法 并且迭代器反会的values 属性存在一个变量值,直到循环到done
属性为true时终止循环
结合 来了解 for-of 更加 迭代器(Iterator)和生成器 (Generator)
let list = [11, 22, 33, 44, 55];
for (const key of list) {
console.log(key);
}
//在这段代码中for-of 中其实是调用的是数组 list 的 Symbol.iterator 属性来获取迭代器 随之调用多次next() 并且value 属性读取值存储到num中 当done 为true 推出循环 所以后的 value 不会为 undefind
// for -of 用到不可迭代对象上面会造成报错
let values = [1, 2, 3];
values = values[Symbol.iterator]();
console.log(values.next()); //{ value: 1, done: false }
console.log(values.next()); //{ value: 2, done: false }
console.log(values.next()); //{ value: 3, done: false }
console.log(values.next()); //{ value: undefined, done: true } 后面都是一样的
console.log(values.next()); //{ value: undefined, done: true }
console.log(values.next()); //{ value: undefined, done: true }
console.log(values.next()); //{ value: undefined, done: true }
// 如何判断是否有迭代器呢
function isIterator(obj) {
// 如果是一个可迭代则是一个 [Function: values]
return obj[Symbol.iterator] instanceof Function;
}
console.log(isIterator([1, 2, 3])); //true
console.log(isIterator("11112222233333")); //true
console.log(isIterator(new Map())); //true
console.log(isIterator(new Set())); //true
console.log(isIterator({})); //false
console.log(isIterator(new WeakMap())); //false
console.log(isIterator(new WeakSet())); //false
// 创建一个可迭代对象,默认情况的对象是不可迭代的,但是在属性中给一个 Symbol.iterator 添加一个生成器 就可以变为一个可迭代对象
let collertion = {
item: [11, 22, 33, 44],
// 这里其实是添加的一个对象,这里是ES6的对象简写 在这里是添加的一个 生成器 因为生成器是可迭代的
//由于生成器为默认为 Symbol.iterator 属性赋值 因此生成器创建的迭代器都是可迭代对象
*[Symbol.iterator]() {
for (const k of this.item) {
yield k; // 这块是返回每一次迭代中的值 这里可以把yield 看做 生成器的next方法
}
},
};
for (const key of collertion) {
console.log(key); //11, 22, 33, 44
}
console.log(Symbol.iterator); //Symbol(Symbol.iterator)
在ES6中有三种数据集合的对象,数组,Set Map 集合,这三个对想都建立了以下三种迭代器
- entries() 返回一个迭代器 值为多个键值对为 [(下标为number),(值,string 会根据集合种的值而来)] Array.entries(): IterableIterator<[number, string]>
- values() 返回一个迭代器 值为集合的值 返回数组中的值的可迭代对象 反回数据类型为 string (method) Array.values(): IterableIterator
- keys() 返回一个迭代器 值为集合种所有的键名 返回映射中的键的可迭代对象 如果遍历是数组则会返回数字类型得键,数组本身得其他值不会返回,如果是Set 由于键和值是相同得 因此 keys 和 values 返回也是相同得迭代器,如果是Map 会返回独立得键
// 使用entries来获取迭代器
let colors = ["red", "gree", "blue"];
let set = new Set([1, 2, 2, 2, 3]);
let map = new Map();
map.set("name", "自夏");
map.set("set", 18);
//entries 获取集合种所存在的值 包含下标
for (const ks of colors.entries()) {
console.log(ks);
/**
* 输出
* [ 0, 'red' ]
[ 1, 'gree' ]
[ 2, 'blue' ]
*/
}
for (const ks of set.entries()) {
console.log(ks);
/**
* 输出
[ 1, 1 ]
[ 2, 2 ]
[ 3, 3 ]
*/
}
for (const ks of map.entries()) {
console.log(ks);
/**
* 输出
*
[ 'name', '自夏' ]
[ 'set', 18 ]
*/
}
//values 获取每一个迭代的值
for (const ks of colors.values()) {
console.log(ks);
/**
* 输出
red
gree
blue
*/
}
for (const ks of set.values()) {
console.log(ks);
/**
* 输出
1
2
3
*/
}
for (const ks of map.values()) {
console.log("values", ks);
/**
* 输出
自夏
18
*/
}
//keys 会获取每一个集合种的键
for (const ks of colors.keys()) {
console.log(ks);
/**
* 输出
0
1
2
*/
}
for (const ks of map.keys()) {
console.log(ks);
/**
* 输出
name
set
*/
}
for (const ks of set.keys()) {
console.log(ks);
/**
* 输出
1
2
3
*/
}
// 暂停,看上一张的 Set Map 对这个还不太熟悉
for (const [key, value] of map) {
console.log(key, value);
}
// 不同得集合默认不同得迭代器 数组和Set 默认得得是values() Map 默认迭代器用的是 entries()
// 使用结构 for of 与 Map 集合
map = new Map([
["name", "自夏"],
["sex", 18],
]);
for (const [key, val] of map.entries()) {
console.log(key, val);
/**
* 输出
name 自夏
sex 18
*/
}