5、Iterator和for...of循环—ES6学习笔记
2017-09-04 10:57
232 查看
基本概念:
在ES6中新增了Set和Map两种数据结构,再加上JS之前原有的数组和对象,这样就有了四种数据集合,平时还可以组合使用它们,定义自己的数据结构,比如数组的成员是Map,Map的成员是对象等。这样就需要一种统一的接口机制,来处理所有不同的数据结构。
Iterator就是这样一种机制。它是一种接口,为各种不同的数据结构提供统一的访问机制。任何数据结构只要部署Iterator接口,就可以完成遍历操作,而且这种遍历操作是依次处理该数据结构的所有成员。
Iterator遍历器的做用:
为各种数据结构,提供一个统一的、简便的访问接口。
使得数据结构的成员能够按某种次序排列。
ES6新增了遍历命令for…of循环,Iterator接口主要供for…of消费。
1 手写 Iterator 接口
Iterator就是数据结构下面的某个方法,我们以数组举个例子
![](https://img-blog.csdn.net/20170904095959565?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQveHlwaGY=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
Iterator的遍历过程:
首先创建一个指针对象,指向当前数据结构的起始位置。也就是说,遍历器对象本质上,就是一个指针对象。接下来依次的调用next方法,去遍历数据结构的每一个成员,直到遍历完成为止。
每次调用next方法都会返回数据结构当前成员的信息.就是的说就是返回包含value和done两个属性的对象。
其中value是当前属性的值,而done属性是一个布尔值.表示遍历是否结束。在遍历过程中done始终是false,而在遍历结束之后,done就变成了true
第一次调用指针对象的next方法,可以将指针指向数据结构的第一个成员。
第二次调用指针对象的next方法,指针就指向数据结构的第二个成员。
不断调用指针对象的next方法,直到它指向数据结构的结束位置。
每一次调用next方法,都会返回数据结构的当前成员的信息。具体来说,就是返回一个包含value和done两个属性的对象。其中,value属性是当前成员的值,done属性是一个布尔值,表示遍历是否结束。
了解了基本的遍历过程之后,在ES6中有些数据结构原生就具备了iterator,比如说数组,Set等,但是有些就没有,比如说对象,
所以说这时我们需要去区分一下,那些数据结构具备iterator接口.
在ES6中决定了如果说一个数据结构具备了Symbol.iterator 属性,那么这个数据结构就具备 Iterator 接口
2 凡是具有 Symbol.iterator 属性的数据结构都具有 Iterator 接口
下面我们举个例子,先声明三个常量,分别是一个数组和一个set和一个map,分别给它们初始化一些数据,之后我们用三个常量保存一下 Iterator 接口,并且执行一下这个函数
这个时候我们就发现了打印出了这三个数据结构的对象指针
![](https://img-blog.csdn.net/20170904102424209?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQveHlwaGY=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
接下来我们就可以使用next方法去遍历数据结构了
我们以set为例
![](https://img-blog.csdn.net/20170904102701754?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQveHlwaGY=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
这时我们发现打印出了a,b,c已经最后一次的undefined,以及done的值变成true,证明这次的变量完成了
为了形成对比,我们在声明一个对象obj
可以发现控制台打印出来的值是一个undefined,证明了对象这种数据结构,原生并不具备Iterator
Symbol是ES6中新增的一种数据类型,在这里我们只需要把它当作成一个普通的属性名就可以了
3 具备iterator接口的数据结构都可以进行如下操作
解构赋值
扩展运算符
证明set这种数据结构可以进行解构赋值
所以但凡是具备iterator接口的数据结构都可以进行解构赋值
除了结构赋值以外,还有一个扩展运算符,扩展运算符实际上就是…,他的作用就是将一个数据结构进行展开
举个例子
首先我们声明一个字符串,字符串是一个类数组,而且也具备iterator接口,所以就可以使用扩展运算符将其展开
接下来我们再举一个例子,
ES6数组去重
从上面的例子我们知道凡事具备iterator接口的数据结构,都可以使用扩展运算符
4 for…of循环
凡事具备iterator接口的数据结构都可以进行for…of循环
我先以数组为例,了解一下for…of循环的基本语法
我们在举一个例子
data既然是一个数组,我们还可以使用解构赋值的方式去遍历Map这种数据结构
在ES6中新增了Set和Map两种数据结构,再加上JS之前原有的数组和对象,这样就有了四种数据集合,平时还可以组合使用它们,定义自己的数据结构,比如数组的成员是Map,Map的成员是对象等。这样就需要一种统一的接口机制,来处理所有不同的数据结构。
Iterator就是这样一种机制。它是一种接口,为各种不同的数据结构提供统一的访问机制。任何数据结构只要部署Iterator接口,就可以完成遍历操作,而且这种遍历操作是依次处理该数据结构的所有成员。
Iterator遍历器的做用:
为各种数据结构,提供一个统一的、简便的访问接口。
使得数据结构的成员能够按某种次序排列。
ES6新增了遍历命令for…of循环,Iterator接口主要供for…of消费。
1 手写 Iterator 接口
Iterator就是数据结构下面的某个方法,我们以数组举个例子
const arr = [1, 2, 3]; // 接下来我们写一个方法,名字叫做iterator,这个函数的参数就是一个数组 function iterator(arr){ // 在函数中先定一个变量等于0 let index = 0; // 这个对象的返回值就是一个对象指针 return { // 在对象指针当中有一个next这样的方法对应一个函数 next: function (){ // 这个函数的返回值需要做一个判断 // 如果index小于arr.length,那么咱们就返回一个对象,这个对象里面有两个属性 // 一个是value,分别表示当前遍历的arr[index],第二个属性是done,代表着是否遍历完成 // 如果条件成立证明没有遍历完成,那么它的值就是一个false // 否则我们返回另一个对象,value值是undefined,因为此时index已经大于等于arr.length,done的值是true,表示已经遍历完成 return index < arr.length ? {value: arr[index++], done: false} : {value: undefined, done: true}; } } } // 这样iterator接口就写完了,我们可以做一个测试 // 我们声明一个常量,把我们的数组传进去,之后我们4次console.log(it.next()) const it = iterator(arr); console.log(it.next()); console.log(it.next()); console.log(it.next()); console.log(it.next()); // 由于数组里面只有三个元素,所以前三个value值打印出的就是1,2,3 // 而第四次由于已经遍历完成了,所以value值对应的就是undefined,done就是true,代表已经遍历完成
Iterator的遍历过程:
首先创建一个指针对象,指向当前数据结构的起始位置。也就是说,遍历器对象本质上,就是一个指针对象。接下来依次的调用next方法,去遍历数据结构的每一个成员,直到遍历完成为止。
每次调用next方法都会返回数据结构当前成员的信息.就是的说就是返回包含value和done两个属性的对象。
其中value是当前属性的值,而done属性是一个布尔值.表示遍历是否结束。在遍历过程中done始终是false,而在遍历结束之后,done就变成了true
第一次调用指针对象的next方法,可以将指针指向数据结构的第一个成员。
第二次调用指针对象的next方法,指针就指向数据结构的第二个成员。
不断调用指针对象的next方法,直到它指向数据结构的结束位置。
每一次调用next方法,都会返回数据结构的当前成员的信息。具体来说,就是返回一个包含value和done两个属性的对象。其中,value属性是当前成员的值,done属性是一个布尔值,表示遍历是否结束。
了解了基本的遍历过程之后,在ES6中有些数据结构原生就具备了iterator,比如说数组,Set等,但是有些就没有,比如说对象,
所以说这时我们需要去区分一下,那些数据结构具备iterator接口.
在ES6中决定了如果说一个数据结构具备了Symbol.iterator 属性,那么这个数据结构就具备 Iterator 接口
2 凡是具有 Symbol.iterator 属性的数据结构都具有 Iterator 接口
下面我们举个例子,先声明三个常量,分别是一个数组和一个set和一个map,分别给它们初始化一些数据,之后我们用三个常量保存一下 Iterator 接口,并且执行一下这个函数
const arr = [1, 2, 3]; const set = new Set(['a', 'b', 'c']); const map = new Map([['a', 1]]); const itArr = arr[Symbol.iterator](); const itSet = set[Symbol.iterator](); const itMap = map[Symbol.iterator](); // 现在我分别取打印一下itArr,itSet,itMap console.log(itArr); console.log(itSet); console.log(itMap);
这个时候我们就发现了打印出了这三个数据结构的对象指针
接下来我们就可以使用next方法去遍历数据结构了
我们以set为例
console.log(itSet.next()); console.log(itSet.next()); console.log(itSet.next()); console.log(itSet.next());
这时我们发现打印出了a,b,c已经最后一次的undefined,以及done的值变成true,证明这次的变量完成了
为了形成对比,我们在声明一个对象obj
const obj = {}; console.log(obj[Symbol.iterator]);
可以发现控制台打印出来的值是一个undefined,证明了对象这种数据结构,原生并不具备Iterator
Symbol是ES6中新增的一种数据类型,在这里我们只需要把它当作成一个普通的属性名就可以了
3 具备iterator接口的数据结构都可以进行如下操作
解构赋值
扩展运算符
let [x, y] = set; console.log(x, y); // a b
证明set这种数据结构可以进行解构赋值
所以但凡是具备iterator接口的数据结构都可以进行解构赋值
除了结构赋值以外,还有一个扩展运算符,扩展运算符实际上就是…,他的作用就是将一个数据结构进行展开
举个例子
首先我们声明一个字符串,字符串是一个类数组,而且也具备iterator接口,所以就可以使用扩展运算符将其展开
let str = 'zhang'; // 这里我们再写上一个数组str, let arrStr = [...str]; // 我们可以将它打印出来 console.log(arrStr);// 我们看见打印出了zhang这个字符串每一项组成的数组
接下来我们再举一个例子,
ES6数组去重
const arr2 = [{}, 1, 'a', 1, 'a', 'b', []]; // Set这种数据结构它是一个集合,集合是不允许出现重复的值的,所以我们就可以使用set这种数据结构为数组去重 // 直接console.log(new Set()); // 然后把arr2当做参数传入进去,之后把这个整体用数组包一下 // 在使用一些扩展运算符 console.log([...new Set(arr2)]); //这时我们发现就打印出了去重之后的数组
从上面的例子我们知道凡事具备iterator接口的数据结构,都可以使用扩展运算符
4 for…of循环
凡事具备iterator接口的数据结构都可以进行for…of循环
我先以数组为例,了解一下for…of循环的基本语法
const ofArr = [1, 2, 3, 4]; for(let i of ofArr){ console.log(i); // 打印数组中的每一项 }
我们在举一个例子
//我们声明一个Map对象,并且向其中添加一个键值对 const m = new Map(); m.set('a', 1).set('b', 2).set('c', 3); for(let data of m){ console.log(data); // 这样就打印出了每个键值对,并且是一个数组 }
data既然是一个数组,我们还可以使用解构赋值的方式去遍历Map这种数据结构
for(let [key, value] of m){ console.log(key, value);//这样就打印出了每个key以及每个key的value值 }
相关文章推荐
- ES6学习笔记(七)Iterator和for...of循环
- ES6学习笔记之Iterator和for...of循环
- es6学习笔记(7)--Iterator 和 for...of 循环
- 学习笔记:ES6之Iterator接口和for…of循环
- ECMAScript 6 学习笔记----Iterator和for...of循环
- es6 javascript的Iterator 和 for...of 循环
- ES6 之 Set数据结构和Map数据结构 Iterator和for...of循环
- ES6(Iterator 和 for...of 循环)
- es6 iterator和for...of循环
- 迭代器(iterator)和for...of循环
- ES6(二) Iterator(遍历器)和for-of循环
- 第十三节,Iterator和for...of循环
- js-ES6学习笔记-for...of循环
- ES6新特性二:Iterator(遍历器)和for-of循环详解
- 深入解读JavaScript中的Iterator和for-of循环
- ECMAScript6笔记:Iterator和for...of循环
- 15.Iterator和for...of循环
- JS中数据结构的遍历--Iterator和for...of循环
- 深入解读JavaScript中的Iterator和for-of循环