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. (转)sdd for aix 安装及基本命令

    总结出自多个文件(自己做的项目和网上找的资料) 原文:http://blog.csdn.net/yujin2010good/article/details/11395701 一.sddpcm安装 要安 ...

  2. 既然有了HBase,为什么还需要Kudu呢?

    不多说,直接上干货! 那既然有了HBase,为什么还需要Kudu呢? 简单的说,就是嫌弃HBase在OLAP(联机分析处理)场合,SQL/MR类的批量检索场景中,性能不够好.通常这种海量数据OLAP场 ...

  3. 04-spring中的aop演示

    1 xml配置 1 导包 2 准备对象 package www.test.service; public interface UserService { public abstract void ad ...

  4. IOS如何打越狱包xcode无证书打包ios应用

    本文要介绍的是在无证书的情况下如何将自己应用打包出去在越狱设备上使用或发给第三方使用企业签名进行应用分发. 前提条件:拥有appleId账号,并且该账号已经注册开发者中心(无需花钱) 教程开始: 1. ...

  5. Fluent API配置

    1.Fluent API配置Model试用行更广 2.使用方法: public class TransferConfig: EntityTypeConfiguration<TransferInf ...

  6. java 多线程操作(锁)

    1.对象的加锁及其操作 程序中单独的并发线程对同一对象进行操作的代码段,成为临界区.java语言中的临界区可以是一个语句块 或者方法,使用关键字synchronized进行标识. 对象锁:java平台 ...

  7. maven课程 项目管理利器-maven 3-3 maven中的坐标和仓库

    本节主要讲了两大方面: 1 maven坐标 1.0  构件定义 任何依赖,插件,项目构建输出 都称之为构件. 1.1 maven坐标概念 groupid 公司或组织的域名倒序+当前项目名称 artif ...

  8. winform文件拖入

    //view.AllowDrop = true; ---------------------------------------- private void view_DragEnter(DragEv ...

  9. (生产)vuex - 状态管理

    参考:https://vuex.vuejs.org/zh-cn/ 安装 直接下载 / CDN 引用 https://unpkg.com/vuex在 Vue 之后引入 vuex 会进行自动安装:< ...

  10. 栅格那点儿事(一)---Raster是个啥子东西

    Raster是个啥子东西 现如今,不仅是在遥感应用中能看到花花绿绿的影像了,在GIS应用中也能随处看到她们的身影.在各种在线地图中,卫星影像作为底图与矢量的道路层叠加:高程DEM作为高程来源实现地形的 ...