forEach、for...in、for...of
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);
}
参考:
forEach、for...in、for...of的更多相关文章
- 集合、拆箱、装箱、自定义集合的foreach
集合部分 参考:http://msdn.microsoft.com/zh-cn/library/0ytkdh4s(v=vs.110).aspx 集合类型是诸如哈希表.队列.堆栈.包.字典和列表等数据集 ...
- javascript中 for in 、for 、forEach 、for of 、Object.keys().
一 .for ..in 循环 使用for..in循环时,返回的是所有能够通过对象访问的.可枚举的属性,既包括存在于实例中的属性,也包括存在于原型中的实例.这里需要注意的是使用for-in返回的属性因各 ...
- for、forEach、for in、for of用法
循环遍历数组或者对象,for.forEach.for in . for of 使用最多 for循环 自Javascript诞生时就有,遍历数组,for 循环的语法如下: for (语句 1; 语句 2 ...
- 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.字面量 ...
- MVC5 网站开发之六 管理员 2、添加、删除、重置密码、修改密码、列表浏览
目录 奔跑吧,代码小哥! MVC5网站开发之一 总体概述 MVC5 网站开发之二 创建项目 MVC5 网站开发之三 数据存储层功能实现 MVC5 网站开发之四 业务逻辑层的架构和基本功能 MVC5 网 ...
- SolrNet高级用法(分页、Facet查询、任意分组)
前言 如果你在系统中用到了Solr的话,那么肯定会碰到从Solr中反推数据的需求,基于数据库数据生产索引后,那么Solr索引的数据相对准确,在电商需求中经常会碰到菜单.导航分类(比如电脑.PC的话会有 ...
- MYSQL、PHP基础、面向对象基础简单复习总结
一.MYSQL 1.配置MySql 第一步安装服务器(apache). 第二部安装MySql界面程序 2 ...
- C#与Java对比学习:数据类型、集合类、栈与队列、迭达、可变参数、枚举
数据类型: C#:String与StringBuilder Java:String与StringBuffer 第一个不习惯是string的第一个字母必须大写了. 第二个不习惯是int得写成Intege ...
- 用Canvas+Javascript FileAPI 实现一个跨平台的图片剪切、滤镜处理、上传下载工具
直接上代码,其中上传功能需要自己配置允许跨域的文件服务器地址~ 或者将html文件贴到您的站点下同源上传也OK. 支持: 不同尺寸图片获取. 原图缩小放大. 原图移动. 选择框大小改变. 下载选中的区 ...
随机推荐
- Murano Weekly Meeting 2016.06.07
Meeting time: 2016.June.7 1:00~2:00 Chairperson: Kirill Zaitsev, from Mirantis Meeting summary: 1.A ...
- (转)Rsync 排错案例解析
Rsync 排错案例解析 原文:http://blog.51cto.com/irow10/1827306 错误一. 执行计划任务的备份脚本后没有看到备份的文件 1.首先查看crontab日志是否执行文 ...
- PHP中的header()函数
PHP header 函数的用法及其注意事项 void header ( string $string [, bool $replace = true [, int $http_response_co ...
- MS-DOS
MS-DOS doskey /history /reinstall /buffersize /macros doskey di=dir /w/p defrag 磁盘碎片整理 xcopy deltree ...
- Unity C# ref与out
ref和out 都是按地址传递的,使用后都将改变原来的数值.ref 方法参数关键字使方法引用传递到方法的同一个变量.当控制传递回调用方法时,在方法中对参数所做的任何更改都将反映在该变量中.若要使用 r ...
- 模糊查询(like)
1. 找出名中包含 “厂”的所有供应商的名select * from provider where pro_name like '%厂%'2.第二个字为华select * from provider ...
- Jquery获取父元素
jquery获取父元素 方法:parent(),parents(),closest() 栗子: <ul class="parent1"> <li><a ...
- MyBatis01--------概念
主程序 读取配置 主配置文件 SQL映射文件 1.什么是框架? ① 框架是一个应用程序的半成品 一个框架程序员可以配置的选择.选项越多,认为这款框架的可扩展性强. 面向 ...
- DataColumn.Expression提示“...循环引用”的错误
我碰到这个问题的时候,在网上找了找,找到了有好几个提出这个问题的人,但是都没有得到解答,当时很郁闷.然后再看看msdn中的解释与自己的测试,才把这个问题给解决了. 代码如下: person.Colum ...
- Java反射破坏单例模式
今天电话面试的时候问到了,Google了一下 原出处: http://blog.csdn.net/lws332969674/article/details/8125893 一. Java中的反射技术可 ...