es6之iterator,for...of
遍历器(Iterator)是一种统一的接口机制,来处理所有不同的数据结构。
JavaScript 原有的表示“集合”的数据结构,主要是数组(Array)和对象(Object),ES6 又添加了Map和Set。这样就有了四种数据集合,用户还可以组合使用它们,定义自己的数据结构,比如数组的成员是Map,Map的成员是对象。这样就需要一种统一的接口机制,来处理所有不同的数据结构。
Iterator 的作用有三个:
一是为各种数据结构,提供一个统一的、简便的访问接口;
二是使得数据结构的成员能够按某种次序排列;
三是 ES6 创造了一种新的遍历命令for...of循环
每一次调用next方法,都会返回数据结构的当前成员的信息。具体来说,就是返回一个包含value和done两个属性的对象。其中,value属性是当前成员的值,done属性是一个布尔值,表示遍历是否结束。
{
let arr=['hello','world'];
let map=arr[Symbol.iterator]();
console.log(map.next());
console.log(map.next());
console.log(map.next());
}
//{value: "hello", done: false}
// {value: "world", done: false}
//{value: undefined, done: true}
ES6 规定,默认的 Iterator 接口部署在数据结构的Symbol.iterator属性,或者说,一个数据结构只要具有Symbol.iterator属性,就可以认为是“可遍历的”(iterable)。Symbol.iterator属性本身是一个函数,就是当前数据结构默认的遍历器生成函数。执行这个函数,就会返回一个遍历器。至于属性名Symbol.iterator,它是一个表达式,返回Symbol对象的iterator属性,这是一个预定义好的、类型为 Symbol 的特殊值,所以要放在方括号内.
const obj = {
[Symbol.iterator] : function () {
return {
next: function () {
return {
value: 1,
done: true
};
}
};
}
};
原生具备 Iterator 接口的数据结构如下。
- Array
- Map
- Set
- String
- TypedArray
- 函数的 arguments 对象
- NodeList 对象
let arr = ['a', 'b', 'c'];
let iter = arr[Symbol.iterator](); iter.next() // { value: 'a', done: false }
iter.next() // { value: 'b', done: false }
iter.next() // { value: 'c', done: false }
iter.next() // { value: undefined, done: true }
上面代码中,变量arr是一个数组,原生就具有遍历器接口,部署在arr的Symbol.iterator属性上面。所以,调用这个属性,就得到遍历器对象。
对于原生部署 Iterator 接口的数据结构,不用自己写遍历器生成函数,for...of循环会自动遍历它们。除此之外,其他数据结构(主要是对象)的 Iterator 接口,都需要自己在Symbol.iterator属性上面部署,这样才会被for...of循环遍历。
{
let obj={
start:[1,3,2],
end:[7,9,8],
[Symbol.iterator](){
let self=this;
let index=0;
let arr=self.start.concat(self.end);
let len=arr.length;
return {
next(){
if(index<len){
return {
value:arr[index++],
done:false
}
}else{
return {
value:arr[index++],
done:true
}
}
}
}
}
}
for(let key of obj){
console.log(key);
}
}
//1
//3
//2
//7
//8
//9
对于类似数组的对象(存在数值键名和length属性),部署 Iterator 接口,有一个简便方法,就是Symbol.iterator方法直接引用数组的 Iterator 接口。
let iterable = {
0: 'a',
1: 'b',
2: 'c',
length: 3,
[Symbol.iterator]: Array.prototype[Symbol.iterator]
};
for (let item of iterable) {
console.log(item); // 'a', 'b', 'c'
}
因为上面这个对象的键名是类似于数组下标的数字,所以可以直接引用数组的iterator.
普通对象部署数组的Symbol.iterator方法,并无效果。
let iterable = {
a: 'a',
b: 'b',
c: 'c',
length: 3,
[Symbol.iterator]: Array.prototype[Symbol.iterator]
};
for (let item of iterable) {
console.log(item); // undefined
}
有了遍历器接口,数据结构就可以用for...of循环遍历.
es6之iterator,for...of的更多相关文章
- ES6的Iterator,jquery Fn
ES6的Iterator对象详解 Iterator实现原理 创建一个指针对象,指向当前数据结构的起始位置.也就是说,遍历器对象本质上,就是一个指针对象. 第一次调用指针对象的next方法,可以将指针指 ...
- ES6的Iterator遍历器
JS表示集合的对象主要有Array.Set.Object.Map,在以前,遍历它们需要使用2种不同的方法,而现在,JS提出了Iterator机制,可以给不同的数据结构提供统一的遍历方法,就是for…o ...
- JS的ES6的iterator
一.iterator 1.概念:iterator是一种接口机制,为各种不同的数据结构提供统一的访问机制. 2.作用: 为各种数据结构,提供一个统一的.简便的访问接口: 使得数据结构的成员能够按某种次序 ...
- 前端知识点回顾之重点篇——ES6的Iterator和Generator
Iterator 迭代器是一种接口.是一种机制. 为各种不同的数据结构提供统一的访问机制.任何数据结构只要部署 Iterator 接口,就可以完成遍历操作(即依次处理该数据结构的所有成员). Iter ...
- ES6的 Iterator 遍历器到底是什么?
这节课要讲的是ES6中的Iterator. for...of为啥不遍历Object对象 第十三节我们讲了简单又实用的for...of,我们可以使用它来遍历数组,字符串,Set和Map结构,但是有没有发 ...
- 切图崽的自我修养-[ES6] 迭代器Iterator浅析
Iterator 这真是毅种循环 Iterator不是array,也不是set,不是map, 它不是一个实体,而是一种访问机制,是一个用来访问某个对象的接口规范,为各种不同的数据结构提供统一的访问机制 ...
- Es6 Symbol.iterator
Symbol.iterator 为每一个对象定义了默认的迭代器.该迭代器可以被 for...of 循环结构使用. --描述 当需要迭代一个对象的时候(比如在 for...of 循环的开始时),它的 @ ...
- es6(14)--iterator for ...of循环
//iterator for ...of循环 { let arr=['hello','world']; let map=arr[Symbol.iterator](); console.log(map. ...
- es6之Iterator
1.任何数据结构只要部署了Iterator接口(本质是一个指针对象),也就是部署了Symbol.iterator属性,便可以完成遍历操作:数组原生就具备Iterator接口,就可以用for...of遍 ...
随机推荐
- Ubuntu 16.04修改显示字体大小(包括GNOME/Unity)
在Ubuntu中字体都基本偏大,且和分辨率无关. Unity: 安装Unity Tweak Tool sudo apt-get install unity-tweak-tool GNOME: 打开优化 ...
- 系统无法安装 OfficeControl.ocx 控件如何解决
在OA上要直接查看word等公告文件,就必须安装office控件.要安装office控件,需要在IE浏览器中做相应的设置.如何设置呢,下面由小编具体介绍下. 工具/原料 OA IE浏览器 方法 ...
- paramiko错误信息:Paramiko error: size mismatch in put
在使用paramiko的put往远处服务器上传资源的时候,出现类似下面的错误信息 The code in paramiko's sftp_client.py:putfo() reads at the ...
- C++入门学习——模板
为什么须要模板? 我们已经学过重载(Overloading),对重载函数而言,C++ 通过函数參数(參数个数.參数类型)的正确匹配来调用重载函数.比如.为求两个数的最大值,我们定义 max () 函数 ...
- 软考之J2SE
特别感谢软考让我如今就接触了神奇的java.曾经尽管真不知道java是个神马,看完马士兵的视频发现里面的东西并不陌生.有vb,c++,c#做基础加上这次的J2SE发现原来编程语言有非常多同样的特性.也 ...
- python开发【第4篇】【进程、线程、协程】
一.进程与线程概述: 进程,是并发执行的程序在执行过程中分配和管理资源的基本单位,每一个进程都有一个自己的地址空 间. 线程,是进程的一部分,一个没有线程的进程可以被看作是单线程的.线程有时又被称为轻 ...
- [DLX反复覆盖] poj 1084 Square Destroyer
题意: n*n的矩形阵(n<=5),由2*n*(n+1)根火柴构成,那么当中会有非常多诸如边长为1,为2...为n的正方形,如今能够拿走一些火柴,那么就会有一些正方形被破坏掉. 求在已经拿走一些 ...
- 将mvvmlight 移植到 ios step1
https://github.com/wangrenzhu/SimpleIoc-For-Objective-c simple ios for objective-c 版 基本实现 全部功能 完美实现 ...
- JSP内建对象
① out - javax.servlet.jsp.jspWriter out对象用于把结果输出到网页上. 方法: 1. void clear() ; 清除输出缓冲区的内容,可是不输出到c ...
- cssTest
html <!doctype html> <html> <head> <meta charset="utf-8"> <meta ...