目录

什么是遍历器?什么是可迭代对象?什么是迭代?什么是可枚举属性?

for 循环

while 循环

do... while 循环

for ... in 循环

for ... of 循环

.forEach 循环

.map() 循环

最后,罗列了几个问题点:


什么是遍历器?什么是可迭代对象?什么是迭代?什么是可枚举属性?

遍历器(Iterator)的诞生:

最初 JS 里用来表示“集合”的数据结构,有数组( Array )和对象( Object ),但在 ES6 中添加了 Map 和 Set 。这样就有了四种数据集合,用户还可以组合使用它们,定义自己的数据结构,比如数组的成员是 Map , Map 的成员是对象。这样就需要一种统一的接口机制,来处理所有不同的数据结构。

就这样 遍历器(Iterator)的诞生了

遍历器(Iterator)就是这样一种机制。它是一种接口,为各种不同的数据结构提供统一的访问机制。任何数据结构只要部署 Iterator 接口,就可以完成遍历操作(即依次处理该数据结构的所有成员)。

遍历器(Iterator) 的作用有三个:一是为各种数据结构,提供一个统一的、简便的访问接口;二是使得数据结构的成员能够按某种次序排列;三是 ES6 创造了一种新的遍历命令 for...of 循环,Iterator 接口主要供 for...of 消费。

可迭代对象:

一种数据结构只要部署了 Iterator 接口,我们就称这种数据结构是“可遍历的”(iterable)。

ES6 规定,默认的 Iterator 接口部署在数据结构的 Symbol.iterator 属性,或者说,一个数据结构只要具有 Symbol.iterator 属性,就可以认为是“可遍历的”(iterable)。(见图 img-1)。原生具备 Iterator 接口的数据结构如下。【Array, Map, Set, String, TypedArray, 函数的 arguments 对象, NodeList 对象】

迭代:

迭代是递归的一种特殊形式,是迭代器提供的一种方法,默认情况下是按照一定顺序逐个访问数据结构成员。迭代也是一种遍历行为。

可枚举属性:

在JavaScript中,对象的属性分为可枚举和不可枚举之分,它们是由属性的 enumerable 值决定的。可枚举性决定了这个属性能否被 for…in 查找遍历到。

迭代器:

Symbol.iterator 属性本身是一个函数,就是当前数据结构默认的遍历器生成函数。执行这个函数,就会返回一个.next() 遍历器。

每一次调用 next 方法,都会返回数据结构的当前成员的信息。具体来说,就是返回一个包含 value 和 done 两个属性的对象。其中, value 属性是当前成员的值, done 属性是一个布尔值,表示遍历是否结束。(看下面代码并见图 img-2)

Iterator 的遍历过程:

(1)创建一个指针对象,指向当前数据结构的起始位置。也就是说,遍历器对象本质上,就是一个指针对象。

(2)第一次调用指针对象的 next 方法,可以将指针指向数据结构的第一个成员。

(3)第二次调用指针对象的 next 方法,指针就指向数据结构的第二个成员。

(4)不断调用指针对象的 next 方法,直到它指向数据结构的结束位置。

arrayList: [{name: '小明', age: 12},{name: '小花', age: 10},{name: '小黑', age: 14}
]const iterator = this.arrayList[Symbol.iterator]();
console.log('iterator =>', iterator)// 模拟循环
console.log(iterator.next())
console.log(iterator.next())
console.log(iterator.next())
console.log(iterator.next())

img-1

img-2

for 循环

for 是最早出现的循环,也是最常用的,它是一种循环机制,能够满足大部分的遍历。主要是依靠角标来获取数组内成员。

位置 作用 详解 是否必要
初始化 循环变量 只在循环开始前执行一次,后面轮循环时就不会被执行了 可省略(见 for 例子2)
定义循环条件

每轮循环都会执行条件判断,结果为 true,接着执行下一轮循环

直到为 false 时结束整个 for 循环。

可省略(见 for 例子3)
更新初始化的变量

当处于这个时间节点时(当前这轮循环结束后,

进入下一轮循环条件判断之前)

执行的 更新初始化变量(这句话应该能看的懂吧!)

可省略(见 for 例子4)
循环执行的代码块

简单介绍(注意):

适用于复杂的处理

再循环中 可以利用角标来删除元素,追加元素,修改元素值

它是一种循环机制

三个语句都可省略,但【;】号必须要有

循环体中可以使用 break(跳出循环)和 continue(阻止当前轮循环继续往下执行,并且进入下一轮循环)

可以循环 数组、对象(见 for例子5)、字符串

当省略②时:别忘记在循环体内使用 break,否则循环永远不会结束!

当省略③时:别忘记在循环体内更新 ①,否则可能会造成永远不会结束!

// 语法 结构
for (语句 1; 语句 2; 语句 3) { 循环 执行的代码块...
}// for 例子 1
for (let i=0; i<3; i++) {console.log(i)
}
// for 例子2
// 可省略语句1(比如在循环开始前已经设置了值时)
// 适用场景,i的初始化值是动态获取的
let i = 2;
for (; i<3; i++) { console.log(i)
}
// for 例子3
// 可省略语句2,省略后必须在循环内提供 break 让循环结束。
// 否则循环就无法停下来。这样有可能令浏览器崩溃。
for (let i=0; ; i++) {console.log(i)if(i == 5){break ;}
}
// for 例子4
// 可省略语句3,写在循环体内。
for (let i=0; i<3; ) {console.log(i)i++
}
// for 例子5
// 三个语句都省略
let i = 0; // 语句1,设置在外面
for (; ; ) {if(i == 5){break ; // 语句2,添加条件,避免出现永久循环}console.log(i)i ++; // 语句3,设置在里面
}
// for 例子6
// 通过使用 ES6中新增的 Object.keys() 方法 帮助for可以循环对象
let obj = {name:'小明'age: 12,
}
let keys = Object.keys(obj);
for (let i = 0; i < keys.length; i++){console.log(obj[keys[i]])
}

记住这种两种写法特点,在进行一些特殊情况时的数据处理会对你很有用

// for 特殊写法
// 不知道这种写法,同学们有没有见过
// 将获取数组长度的竟然放在了语句1里面
// 我在文章的上面讲过,语句1,执行一次对吧
// 那么这种写法,它的好处以及坏处,大家看打印结果,你就会明白的
let arr = ['01','02','03'];
for(let i = 0, len = arr.length; i<len; i++){console.log(arr[i], JSON.parse(JSON.stringify(arr)))if(arr[i] == '02'){arr.push('04')}
}
// 输出:01 ['01', '02', '03']
// 输出:02 ['01', '02', '03']
// 输出:03 ['01', '02', '03', '04']// 我在循环中,有个判断,循环到02时,向数组内追加了新的成员。
// 从打印的结果上可以看到,成员是成功追加进去的。可是为什么没有循环出来捏。
// 原因就是因为,获取数组长度,写在了语句1里面,而语句1,只执行一次
// 当执行获取数组长度时,数组的长度就是3,所以整个循环只跑了3轮let arr = ['01','02','03'];
for(let i = 0; i < arr.length; i++){console.log(arr[i], JSON.parse(JSON.stringify(arr)))if(arr[i] == '02'){arr.push('04')}
}
// 输出:01 ['01', '02', '03']
// 输出:02 ['01', '02', '03']
// 输出:03 ['01', '02', '03', '04']
// 输出:04 ['01', '02', '03', '04']// 而这种写法,是在每次轮循时,都去重新获取数组的长度。

while 循环

while 循环只要指定条件结果为 true,循环就可以一直执行代码块。

简单介绍(注意):

别忘记更新条件中所用变量的值,否则循环永远不会结束!

当①结果为true时进入循环

循环体中可以使用 break(跳出循环)

// 语法结构
while (条件){需要执行的代码
}// 该循环永远不会结束,这可能导致浏览器崩溃。
while(true){console.log('加菲猫!')
}const arr = ['1','2',undefined,'3','','4'];
let i = 0;
while(arr[i]){console.log(arr[i])i = i + 1;
}
// 输出: 1
// 输出: 2const arr = ['1','2','3','4'];
let i = 0;
while(arr[i]){console.log(arr[i])i = i + 1;
}
// 输出: 1
// 输出: 2
// 输出: 3
// 输出: 4

do... while 循环

do... while 循环是 while 循环的变体。该循环会在判断条件是否为真之前执行一次代码块,然后如果条件为真的话,就会重复这个循环。

简单介绍(注意):

它具有 即使条件的结果为 false,也至少循环一次的特点

别忘记更新条件中所用变量的值,否则循环永远不会结束!

循环体中可以使用 break(跳出循环)

// 语法结构
do
{需要执行的代码
}
while (条件);
// do while 例子1
const arr = [1,2,3,4];
let i = 0;
let num = 0;
do
{num = num + arr[i]; // 数组内成员的和i++ ;
}while (arr[i]);console.log(num) // 10
//数组中的【0,null,false,undefined, 空字符串】 当做false处理
// do while 例子2
const arr = [null,1,2,3,4];
let i = 0;
let num = 0;
do
{console.log(arr[i])i++ ;
}while (arr[i]);// 角标 0 的位置,我故意放置了一个 null
// 因为先执行的 do 内的代码块 由(i=0) => 变(i=1)
// 所以当第一次进入 while 条件判断时, i变成了1, (arr[1]) => (1)

for ... in 循环

for ... in 是在 ES5 中新增的,遍历所有可枚举的属性(包括原型上的),最好只用来循环对象。

简单介绍(注意):

我觉得它的设计初衷就是循环对象,所以推荐大家用它时最好就是遍历对象

用于 遍历对象的所有可枚举属性、字符串、数组(最好不要使用for...in循环数组)

遍历  数组时 语句①为数组的角标,并且它的 index 索引是字符串型数字

遍历 数组时 循环顺序有可能不是按照实际数组的内部顺序,不推荐使用 通过for ... in循环出来的角标

可以使用 break(跳出循环)和 continue(阻止当前轮循环继续往下执行,并且进入下一轮循环)

// 语法结构
for(let 成员 in 对象){循环的代码块
}
// for in 例子1
const json = {name: '加菲猫',sex: '男',age: '8',
};
for(let item in json){console.log('item =>', item , json[item])
}
// 输出:item => name 加菲猫
// 输出:item => sex 男
// 输出:item => age 8

for ... of 循环

for...of 是在 ES6 中新增的 语句,它遍历一个可迭代的对象(不明白可迭代对象,看文章顶部有关可迭代对象的介绍)

简单介绍(注意):

用于遍历可迭代对象 以及 字符串

想要在 for ...of 中得到数组的索引,需要使用 array.entries() 方法(见 for of 例子2)

可以使用 break(跳出循环)和 continue(阻止当前轮循环继续往下执行,并且进入下一轮循环

// for of 例子1
const arr = [1,2,3];
let item;
for(item of arr){console.log('item =>', item)
}// 输出:item => 1
// 输出:item => 2
// 输出:item => 3
// for of 例子2
// 使用 entries() 方法后,语句1 在每次遍历中就会得到一个数组,格式如下 下方配有截图
// 输出:index => (2) [0, 1]
// 输出:index => (2) [1, 2]
// 输出:index => (2) [2, 3]const arr = [1,2,3];
let item,index;
for([index,item] of arr.entries()){console.log('index =>', index , 'item =>', item)
}// 注意,这种情况下,角标在第一个位置,元素在第二个位置
// 输出:index => 0 item => 1
// 输出:index => 1 item => 2
// 输出:index => 2 item => 3

// for of 例子3
// for of 中使用解构
const arr = [{name: '小A', age: 12},{name: '小B', age: 10},{name: '小C', age: 14},
];
let ages = 0, age = 0;
for({age} of arr){ages = ages + age;
}
console.log('总年龄 =>', ages)
// 输出:总年龄 => 36

.forEach 循环

forEach 是 ES5 提出的,挂载在可迭代对象原型上的方法。forEach是一个遍历器,负责遍历可迭代对象。

位置 详解 是否必要
当前元素 必须
当前元素的角标。 可省略

当前被遍历的数组对象

可省略
回调函数中的this指向,默认为undefined 可省略

简单介绍(注意):

用于遍历 可迭代对象 以及 字符串

forEach() 对于空数组是不会执行回调函数的。

forEach() 中想要跳出循环 可以使用 try/catch。(见 forEach 例子1)

forEach() 中不建议修改正在遍历的可迭代对象内的元素值,避免出现低级错误。

// 语法结构
array.forEach(function(currentValue, index, arr), thisValue)
// forEach 例子1
try{const arr = [1,2,3,4];arr.forEach((item,index,arr) => {console.log('item =>', item)if(item == 2){throw new Error('11') // 抛出异常}})
}catch(e){if (e.message !== "11") throw e;
}console.log('啦啦啦')// 输出:item => 1
// 输出:item => 2
// 输出:啦啦啦
// forEach 例子2
// 遍历对象
const json = {name: '加菲猫',age: 10
}
const kyes = Object.keys(json);
console.log('kyes =>', kyes)
kyes.forEach((item)=>{console.log(item, json[item])
})// 输出:kyes => ['name', 'age']
// 输出:name 加菲猫
// 输出:age 10

.map() 循环

.map() 和 forEach 一样都是 ES5 提出的 ,.map() 方法是挂载在 Array 对象的原型上的 。 基本用法跟 forEach 方法类似。

位置 详解 是否必要
当前元素 必须
当前元素的角标。 可省略

当前被遍历的数组对象

可省略
回调函数中的this指向,默认为undefined 可省略

简单介绍(注意):

.map() 只能遍历 Array对象

.map() 它有返回值(它返回一个新的数组),新数组中的元素 为 原始数组元素 在回调函数内处理后的值。

.map() 不会对空数组进行检测。

.map() 当数组中的值为基本数据类型时不会改变原始数组(当数组内的元素为对象会被改变)。(见 map 例子1)

// 语法结构
array.map(function(currentValue,index,arr), thisValue)
// map 例子1
const arr = [1,2,3];
const hh = arr.map((item, index, arr) =>{item = item + 10;return item;
})
console.log('hh =>', JSON.parse(JSON.stringify(hh))) // 新数组
console.log('arr =>', JSON.parse(JSON.stringify(arr))) // 原数组// 输出:hh => [11, 12, 13]
// 输出:arr => [1, 2, 3]
// map 例子2
const arr = [{id: 1,name: '加菲猫',
},{id: 2,name: '欧弟',
}];
const home = arr.map((item, index, arr) =>{return item.name;
})/*
home 格式如下:
['加菲猫','欧弟'
]
*/

最后,罗列了几个问题点:

1. for...in 与 for...of 的区别,for in 和 for of 打印 item 输出的分别是什么?

const arr = [1,2,3,4,5]

for(let item in arr)

for(let item of arr)

2. for 循环和 forEach 的本质区别是什么?

JS 循环大全 最强详解相关推荐

  1. js购物车功能php,使用JS实现购物车功能步骤详解

    这次给大家带来使用JS实现购物车功能步骤详解,使用JS实现购物车功能的注意事项有哪些,下面就是实战案例,一起来看一下. 我们肯定都很熟悉商品购物车这一功能,每当我们在某宝某东上购买商品的时候,看中了哪 ...

  2. 常用经典SQL语句大全完整版--详解+实例 (存)

    常用经典SQL语句大全完整版--详解+实例 转 傻豆儿的博客 http://blog.sina.com.cn/shadou2012  http://blog.sina.com.cn/s/blog_84 ...

  3. js showModalDialog参数的使用详解(转)

    js showModalDialog参数的使用详解_javascript技巧_脚本之家 http://www.jb51.net/article/45281.htm 本篇文章主要是对js中showMod ...

  4. [js]JavaScript Number.toPrecision() 函数详解

    [js]JavaScript Number.toPrecision() 函数详解 JavaScript: numberObject.toPrecision( [ precision ] ) 如果没有提 ...

  5. node mysql 查询_Node.js使用mysql进行查询详解

    本篇教程介绍了Node.js使用mysql进行查询详解,希望阅读本篇文章以后大家有所收获,帮助大家对Node.js的理解更加深入. < 因为返回的是个对象 var selectSql1=&quo ...

  6. 我的世界服务器ess配置信息,我的世界ess指令大全及用法详解

    我的世界ess指令大全及用法详解告诉你<我的世界>是一款风靡全球的沙盒游戏,其中哟很多的指令可以帮助玩家更好的游戏.ess指令在ess插件运行中十分重要的一部分,但是很多新手玩家在刚开始接 ...

  7. 我的世界ess服务器信息,我的世界ess指令怎么用 ess指令大全及用法详解

    我的世界ess指令都有哪些?作为风靡全球的沙盒游戏,我的世界带给玩家太多的乐趣.为了能更方便的游戏,ess指令能帮助我们更好的游戏.很多新手玩家刚接触就被搞晕了,这么多的指令看起来有些复杂.下面就由小 ...

  8. 我的世界服务器ess配置文件,《我的世界》ess指令大全及用法详解

    我的世界是一款风靡全球的沙盒游戏,其中哟很多的指令可以帮助玩家更好的游戏.ess指令在ess插件运行中十分重要的一部分,但是很多新手玩家在刚开始接触的时候都不是太了解,下面安卓游戏小编就为大家带来我的 ...

  9. js中小括号()的用法详解

    一.js中小括号()的用法详解 1.作为分组运算符: 分组运算符应该是再熟悉不过了,因为在小学数学中就有应用,例如: var a=(1+2)*4; console.log(a); 以上代码的输出值是1 ...

最新文章

  1. IOS初级:UIAlertController
  2. R语言之字符处理(一)
  3. 《HTML5移动应用开发入门经典》—— 1.1 了解HTML5的由来
  4. Oracle-SYSAUX表空间解读
  5. Funny:还是程序猿会玩——弹幕炸天学AI和区块链,玩起来!弹慕君,你也值得拥有!
  6. 关于MCP2515帧连发、多发的坑
  7. WCF生成客户端对象方式解析
  8. java expextion_Java(20~24)
  9. 前端学习(1779):前端调试之cache原理和查看
  10. json介绍及简单示例
  11. 17-sendto函数和异步错误
  12. 小波 奇异点 matlab,Matlab小波变换对于奇异点的检测.doc
  13. 测试额外任务而撒旦法 速度速度发撒旦法
  14. 'Request(okhttp3.Request.Builder)' is not public in 'okhttp3.Request'. Cannot be accessed from outsi
  15. Jetpack LiveData
  16. 前缀树是什么 前缀树的使用场景
  17. Traffic shaping 一个事半功倍的程序化”噪音“解决方案
  18. 景安网络快云mysql版本_景安快云数据库使用教程
  19. 服务器软件维护的内容有哪些
  20. nesting —— 二维不规则多边形排料 —— 测试数据集【付费分享】

热门文章

  1. Win10系统恢复IE 11浏览器
  2. Mysql语句的长度限制
  3. Java 内存模型 侵删
  4. pytest—setup和teardown简单用法
  5. GOJS学习笔记一-初入GOJS(创建节点)
  6. java打包 图片_Java 图片爬虫,java打包jar文件
  7. 每天照此运动15分钟,3个月后你也可以变成健身教练的性感好身材
  8. 手机App与蓝牙手柄
  9. 赛效:怎么在线给Word文档加图片水印
  10. 老交大的人才队伍建设