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. Murano Weekly Meeting 2016.06.07

    Meeting time: 2016.June.7 1:00~2:00 Chairperson:  Kirill Zaitsev, from Mirantis Meeting summary: 1.A ...

  2. (转)Rsync 排错案例解析

    Rsync 排错案例解析 原文:http://blog.51cto.com/irow10/1827306 错误一. 执行计划任务的备份脚本后没有看到备份的文件 1.首先查看crontab日志是否执行文 ...

  3. PHP中的header()函数

    PHP header 函数的用法及其注意事项 void header ( string $string [, bool $replace = true [, int $http_response_co ...

  4. MS-DOS

    MS-DOS doskey /history /reinstall /buffersize /macros doskey di=dir /w/p defrag 磁盘碎片整理 xcopy deltree ...

  5. Unity C# ref与out

    ref和out 都是按地址传递的,使用后都将改变原来的数值.ref 方法参数关键字使方法引用传递到方法的同一个变量.当控制传递回调用方法时,在方法中对参数所做的任何更改都将反映在该变量中.若要使用 r ...

  6. 模糊查询(like)

    1. 找出名中包含 “厂”的所有供应商的名select * from provider where pro_name like '%厂%'2.第二个字为华select * from provider ...

  7. Jquery获取父元素

    jquery获取父元素 方法:parent(),parents(),closest() 栗子: <ul class="parent1"> <li><a ...

  8. MyBatis01--------概念

    主程序 读取配置 主配置文件 SQL映射文件 1.什么是框架?      ① 框架是一个应用程序的半成品      一个框架程序员可以配置的选择.选项越多,认为这款框架的可扩展性强.       面向 ...

  9. DataColumn.Expression提示“...循环引用”的错误

    我碰到这个问题的时候,在网上找了找,找到了有好几个提出这个问题的人,但是都没有得到解答,当时很郁闷.然后再看看msdn中的解释与自己的测试,才把这个问题给解决了. 代码如下: person.Colum ...

  10. Java反射破坏单例模式

    今天电话面试的时候问到了,Google了一下 原出处: http://blog.csdn.net/lws332969674/article/details/8125893 一. Java中的反射技术可 ...