forEach

  数组实例的遍历方法

const arr=['red', 'green', 'blue'];
arr.forEach(function(element, index) {
console.log(element);// red green blue
console.log(index);// 0 1 2
});

  forEach这种写法的问题是,无法中途跳出forEach循环,break命令或return命令都不能奏效。

for...in

  JavaScript原有的循环,只能获得对象的键名,不能直接获取键值。

var arr = ['a', 'b', 'c', 'd', 'e'];
for(let i in arr) {
console.log(i);//0 1 2 3 4
}
for(let index in arr) {
console.log(arr[index]);// a b c d e
}
let es6 = {
edition: 6,
committee: "TC-39",
standard: "ECMA-262"
};
for(let e in es6) {
console.log(e);
}
//edition
//committee
//standard

  for...in循环有几个缺点:

    数组键名是数字,但是for...in循环是以字符串作为键名"0","1","2"等

    for...in循环不仅遍历数字键名,还会遍历手动添加的其它键,甚至包括原型链上的键。

    某些情况下,for...in循环会以任意顺序遍历键名。

  总之,for...in循环主要是为遍历对象为设计的,不适用于遍历数组。

for...of

  ES6借鉴C++、Java、C#和Python语言,引入了for...of循环,作为遍历所有数据结构的统一的方法。一个数据结构只要部署了Symbol.iterator属性,就被视为具有iterator接口,就可以用for...of循环遍历它的成员。也就是说,for...of循环内部调用的是数据结构的Symbol.iterator方法。for...of循环可以使用的范围包括数组、Set和Map结构、某些类似数组的对象(比如arguments对象、DOM NodeList对象)、Generator对象以及字符串。

  数组原生具有iterator接口(即默认部署了Symbol.iterator属性),for...of循环本质上就是调用这个接口产生的遍历器,允许遍历获得键值

var arr = ['a', 'b', 'c', 'd', 'e'];
for(let i of arr) {
console.log(i);//a b c d e
}

  for...of循环可以代替数组实例的forEach方法

  for...of循环调用遍历器接口,数组的遍历器接口只返回具有数字索引的属性;这一点与for...in也不一样。

let arr = [1,3,5];
arr.foo = 'hello';
for(let i in arr) {
console.log(i);//'1', '3', '5', 'foo'
} for(let i of arr) {
console.log(i);//'1', '3', '5'
}

  Set和Map结构也原生具有Iterator接口,可以直接使用for...of循环

var engines = new Set(["Gecko", "Trident", "Webkit", "Webkit"]);
for(var e of engines) {
console.log(e);
}
//Gecko
//Trident
//Webkit
var es6 = new Map();
es6.set("edition", 6);
es6.set("committee", "TC39");
es6.set("standard", "ECMA-262");
for(var [name, value] of es6) {
console.log(name+ ":" + value);
}
//edition: 6
//committee: TC39
//standard: ECMA-262

  Set和Map遍历的顺序是按照各个成员被添加进数据结构的先后顺序。其次,Set结构遍历,返回的是一个值。Map结构遍历返回的是一个数组,该数组的两个成员分别为当前Map成员的键名和键值。

  for...of循环,获得数组的索引,可以借助数组实例的entries方法和keys方法。

let arr = ["a", "b", "c"];
for(let pair of arr.entries()) {
console.log(pair);
}
//[0, 'a']
//[1, 'b']
//[2, 'c']

  for...of遍历类似数组的对象(String、DOM NodeList、arguments)

//字符串
let str="hello";
for(let s of str) {
console.log(s);// h e l l o
}
//DOM NodeList对象
let paras = document.querySelectorAll("p");
for(let p of paras) {
p.classList.add("test");
}
//arguments对象
function printArgs() {
for(let x of arguments) {
console.log(x);
}
}
printArgs('a', 'b');
//'a'
//'b'

  对字符串来说,for...of循环还能够正确识别32位UTF-16字符

for (let x of 'a\uD83D\uDC0A) {
console.log(x);
}
//'a'
//'\uD83D\uDC0A'

  并不是所有类似数组的对象都具有Iterator接口,一个方法是用Array.from方法将其转换为数组

let  arrayLike = [length: 2, 0: 'a', 1: 'b'];
for(let x of array.from(arrayLike)) {
console.log(x);
}

  对于普通的对象,for...of结构不能直接使用,必须部署Iterator接口后才能使用。一种解决方法是将对象的键名生成一个数组,然后遍历这个数组:

for(let key of Object.keys(someObject)) {
console.log(key + ":" + someObject[key]);
}

  另一个方法是使用Generator函数

function* entries(obj) {
for(let key of Object.keys(obj)) {
yield [key, obj[key]];
}
}
for(let [key, value] of entries(obj)) {
console.log(key, '->', value);
}
//a -> 1
//b -> 2
//c -> 3

  for...of相对其它遍历方法,有以下优点:

    有着同for...in一样简洁的语法,但是没有for...in那些缺点;

    不同于forEach方法,它可以与break、continue和return配合使用

    提供了遍历所有数据结构的统一操作接口

for(var n of fibonacci) {
if(n>1000)
break;
console.log(n);
}

参考:

Iterator和for...of

forEach、for...in、for...of的更多相关文章

  1. 集合、拆箱、装箱、自定义集合的foreach

    集合部分 参考:http://msdn.microsoft.com/zh-cn/library/0ytkdh4s(v=vs.110).aspx 集合类型是诸如哈希表.队列.堆栈.包.字典和列表等数据集 ...

  2. javascript中 for in 、for 、forEach 、for of 、Object.keys().

    一 .for ..in 循环 使用for..in循环时,返回的是所有能够通过对象访问的.可枚举的属性,既包括存在于实例中的属性,也包括存在于原型中的实例.这里需要注意的是使用for-in返回的属性因各 ...

  3. for、forEach、for in、for of用法

    循环遍历数组或者对象,for.forEach.for in . for of 使用最多 for循环 自Javascript诞生时就有,遍历数组,for 循环的语法如下: for (语句 1; 语句 2 ...

  4. JavaScript基础&实战(5)js中的数组、forEach遍历、Date对象、Math、String对象

    文章目录 1.工厂方法创建对象 1.1 代码块 1.2.测试结果 2.原型对象 2.1 代码 2.2 测试结果 3.toString 3.1 代码 3.2 测试结果 4.数组 4.1 代码 5.字面量 ...

  5. MVC5 网站开发之六 管理员 2、添加、删除、重置密码、修改密码、列表浏览

    目录 奔跑吧,代码小哥! MVC5网站开发之一 总体概述 MVC5 网站开发之二 创建项目 MVC5 网站开发之三 数据存储层功能实现 MVC5 网站开发之四 业务逻辑层的架构和基本功能 MVC5 网 ...

  6. SolrNet高级用法(分页、Facet查询、任意分组)

    前言 如果你在系统中用到了Solr的话,那么肯定会碰到从Solr中反推数据的需求,基于数据库数据生产索引后,那么Solr索引的数据相对准确,在电商需求中经常会碰到菜单.导航分类(比如电脑.PC的话会有 ...

  7. MYSQL、PHP基础、面向对象基础简单复习总结

    一.MYSQL         1.配置MySql                 第一步安装服务器(apache).                 第二部安装MySql界面程序         2 ...

  8. C#与Java对比学习:数据类型、集合类、栈与队列、迭达、可变参数、枚举

    数据类型: C#:String与StringBuilder Java:String与StringBuffer 第一个不习惯是string的第一个字母必须大写了. 第二个不习惯是int得写成Intege ...

  9. 用Canvas+Javascript FileAPI 实现一个跨平台的图片剪切、滤镜处理、上传下载工具

    直接上代码,其中上传功能需要自己配置允许跨域的文件服务器地址~ 或者将html文件贴到您的站点下同源上传也OK. 支持: 不同尺寸图片获取. 原图缩小放大. 原图移动. 选择框大小改变. 下载选中的区 ...

随机推荐

  1. jquery dataTable 自定义 Button及按钮事件

    参考网址:http://stackoverflow.com/questions/18134913/jquery-datatabletabletool-custom-buttons-calling-ev ...

  2. 数据库的ACID跟事务隔离级别

    摘抄:http://blog.csdn.net/shuaihj/article/details/14163713 ------------------------------------------- ...

  3. 手机web前端调试页面的几种方式

    前言 PC端web页面调试比较容易,这里主要说几种移动端调试的方法,从简单到复杂.从模拟调试到远程调试,大概分为几部分: 1.Chrome DevTools(谷歌浏览器)的模拟手机调试 2.weinr ...

  4. Jetty数据同步使用

    1. Jetty简介 Jetty 是一个开源的servlet容器,它为基于Java的web容器,例如JSP和servlet提供运行环境.Jetty是使用Java语言编写的,它的API以一组JAR包的形 ...

  5. MySQL设置允许用户远程登录

    . //登录数据库 mysql -u root -pvmwaremysql>use mysql; //%为所有ip都可以远程访问 mysql>update user set host = ...

  6. 批量删除QQ空间说说

    第一步:用电脑打开浏览器登录你的QQ空间 第二步:点击你的说说栏目 第三步:按下电脑的F12键或者点击右上角的菜单一栏,点击开发者工具 第四步:看到右半边屏幕,找到一个叫Console的菜单,并且点击 ...

  7. Hive总结

    一.什么是Hive 1.Hive 由 Facebook 实现并开源 2.是基于 Hadoop 的一个数据仓库 3.可以将结构化的数据映射为一张数据库表 4.并提供 HQL(Hive SQL)查询功能 ...

  8. div模拟textarea自适应高度

    之前在公司做项目的时候,有这么一个需求,要我写一个评论框,可以随着评论的行数增加而自动扩大,最开始我想用textarea实现,但是后来尝试后发现textarea并不适合,textarea的高度不会随着 ...

  9. centos yum 安装jdk后配置JAVA_HOME

    centos6.4 yum 安装jdk和JAVA_HOME的设置 2014-06-17 16:13 1176人阅读 评论(0) 收藏 举报  分类: linux(3)  版权声明:本文为博主原创文章, ...

  10. centos7服务器搭建javaweb运行环境及代码部署

    之前在一直在学习java web终于写完了第一个小demo,于是在阿里云上买了一个服务器,开始了配置服务器环境的踩坑之旅.... ps:本文不讨论服务器配置的具体步骤,网上都很多,按部就班就是,本文主 ...