神奇的 for 循环代码执行顺序并不是按照代码书写顺序执行,这就导致在看很多程序算法的时候,会有那么一点打脑壳。

for 语法

for 循环的语法很简单,重点是小括号里面的三个部分,这三部分的执行顺序对于不太懂程序的兄弟来说,可以把人晃晕~

for (初始化; 条件; 增量) {
// 循环体
}

初始化 部分仅在进入循环时候执行,条件 部分会在每次循环开始时执行,增量 部分在每次循环最后执行。

语言乏力,下面看图解。

图解

先看这么一段代码:

console.log('start')
for (
let i = 0;
i < 3;
i++
) {
console.log(i);
}
console.log('end')

对于代码输出,一口都可以说出来:

start
0
1
2
end

但对于代码的执行顺序,就不太好说了~~

先加一个 debugger 让代码断点,利用断点来看执行顺序。

如下图:

逐步解析

1、程序进入断点。

2、执行了 console.log('start'),输出打印 start。

【3、4、5、6】第一次循环

3、执行初始化语句 let i = 0,变量 i 赋值 0 作为初始条件。

4、执行条件判断 i < 3,i=0 小于 3,进入循环体。

5、执行循环体 console.log(i),输出打印 0。

6、执行增量语句 i++,i 变为 1。

【7、8、9】第二次循环

7、执行条件判断 i < 3,i=1 小于 3,再次进入循环体。

8、执行循环体 console.log(i),输出打印 1。

9、执行增量语句 i++,i 变为 2。

【10、11、12】第三次循环

10、执行条件判断 i < 3,i=2 小于 3,继续进入循环体。

11、执行循环体 console.log(i),输出打印 2。

12、执行增量语句 i++,i 变为 3。

13、开始第四次循环判断 i < 3,由于 i=3 已经不小于 3,所以循环终止。

14、执行 console.log('end') ,输出打印 end,整个代码段结束。

可以看到,增量语句是在每次循环体执行完之后再执行的,其执行顺序与书写顺序是不相关的!

for 变体

根据上面的执行顺序,可以推断 for 循环其实是可以改变写法的,小括号中的三部分都可以省略。

1、省略初始化语句

let i = 0;
for (; i < 3; i++) {
console.log(i);
}
console.log('end')

2、省略条件判断语句

for (let i = 0; ; i++) {
if (i >= 3) {
break;
}
console.log(i);
}
console.log('end')

3、省略增量语句

for (let i = 0; i < 3; ) {
console.log(i);
i++;
}
console.log('end')

4、省略所有语句

let i = 0;
for (;;) {
if (i >= 3) {
break;
}
console.log(i);
i++;
}
console.log('end')

虽然省略这些条件的代码有些奇葩,但语法规则又允许这么写,那么就有必要了解下这些变体写法,以防拿到这样的代码之后就懵了~~

写在最后

单个 for 循环很简单,但算法中的循环可不止一个,层层嵌套下来之后,再叠加上递归 Buff,那代码看起来就打脑壳了,所以搞算法的大佬们都值得膜拜~~

分享一个数组快速排序的代码,验证下代码阅读能力:

function quickSort(arr) {
// 数组小于 1 不用排序,直接返回即可
if(arr.length <= 1) {
return arr;
} const p = arr[Math.floor(arr.length / 2)]; // 使用中间元素作为比较的基准值
const left = []; // 左分区
const right = []; // 右分区
const equal = []; // 等于基准点的元素 // 遍历给左右分区
for(let i = 0; i < arr.length; i++) {
const item = arr[i];
if(item < p) {
// 小于基准点放在左边
left.push(item)
}else if (item > p) {
// 大于基准点方在右边
right.push(item)
} else {
equal.push(item)
}
}
// 合一并且对左右分区,递归处理
return quickSort(left).concat(equal, quickSort(right))
} // 使用
const tempArr = [3, 6, 8, 10, 1, 2, 1];
console.log(quickSort(tempArr)); // [1, 1, 2, 3, 6, 8, 10]

Web前端入门第 63 问:JavaScript 图解 for 循环执行顺序的更多相关文章

  1. web前端入坑第五篇:秒懂Vuejs、Angular、React原理和前端发展历史

    秒懂Vuejs.Angular.React原理和前端发展历史 2017-04-07 小北哥哥 前端你别闹 今天来说说 "前端发展历史和框架" 「前端程序发展的历史」 「 不学自知, ...

  2. Android零基础入门第63节:过时但仍值得学习的选项卡TabHost

    原文:Android零基础入门第63节:过时但仍值得学习的选项卡TabHost 由于前几天参加一个学习培训活动,几乎每天都要从早晨7点到晚上一两点,没有什么时间来分享,实在抱歉中间断更了几天.从今天开 ...

  3. php课程 1-3 web项目中php、html、js代码的执行顺序是怎样的(详解)

    php课程 1-3 web项目中php.html.js代码的执行顺序是怎样的(详解) 一.总结 一句话总结:b/s结构 总是先执行服务器端的先.js是客户端脚本 ,是最后执行的.所以肯定是php先执行 ...

  4. 关于JavaScript预编译和执行顺序以及函数引用类型的思考

    昨晚在对项目中的一部分做模块化处理的时候,遇到了一个问题,一个重新定义的function对一个通用类中的function进行赋值覆盖的时候,失败了.问题抽象出来是这样的: <script > ...

  5. web前端入坑第二篇:web前端到底怎么学?干货资料! 【转】

    http://blog.csdn.net/xllily_11/article/details/52145172 版权声明:本文为博主[小北]原创文章,如要转载请评论回复.个人前端公众号:前端你别闹,J ...

  6. web前端(13)—— 了解JavaScript,JavaScript的引入方式

    从本篇博文开始,将进入web前端方便最关键最重要的部分——javascript,学到后面你就知道它真的太重要了 什么是JavaScript JavaScript一种直译式的脚本语言,是一种动态类型.弱 ...

  7. WEB前端工程师整理的原生JavaScript经典百例

    一.原生JavaScript实现字符串长度截取 二.原生JavaScript获取域名主机 三.原生JavaScript转义html标签 四.原生JavaScript时间日期格式替换 Date.prot ...

  8. Web前端基础怎么学? JavaScript、html、css知识架构图

    以前开发者只要掌握 HTML.CSS.JavaScript 三驾马车就能胜任一份前端的工作了.而现在除了普通的编码以外,还要考虑如何性能优化,如何跨端.跨平台实现功能,尤其是 AI.5G 技术的来临, ...

  9. web前端学习之HTML CSS/javascript之一

    前端编码之路之坎坷,web前端应该一直是个战场吧,各种浏览器的不兼容,各种小细节的修改,要往一个好的产品经理方向走,实在是难,昨天听了一位十年经验的产品经理讲座,最重要的恐怕就是协调资源的能力,而协调 ...

  10. web前端学习(四)JavaScript学习笔记部分(1)-- JavaScript基础教程

    1.JavaScript基础教程 1.1.Javascript基础-介绍.实现.输出 1.1.1.JavaScript是互联网上最流行的脚本语言,这门语言可用于web和HTML,更可广泛用于服务端.p ...

随机推荐

  1. k8s:The connection to the server localhost:8080 was refused - did you specify the right host or port?

    前言 k8s 集群 node节点报错:The connection to the server localhost:8080 was refused - did you specify the rig ...

  2. go ceph s3文件管理

    导入依赖 go get gopkg.in/amz.v1/aws go get gopkg.in/amz.v1/s3 创建用户 在初始化连接之前,我们需要创建一个用户得到accessKey和secret ...

  3. Git--命令常用

    GITLab 命令 git remote add origin https://gitee.com/gtnotgod/Data-Quality-Management.git #增加了远程仓库 git ...

  4. nginx中的路径匹配规则详解(location规则)

    Nginx的路径匹配规则 Nginx的匹配规则用location指令来实现,Nginx 的location指令用于匹配请求的 URI(请求路径),并根据匹配结果执行特定的处理指令.location是实 ...

  5. 静态批处理/动态批处理/GPU Instancing /SRP Batcher的详细剖析

    静态批处理[1] 定义 标明为 Static 的静态物件,如果在使用相同材质球的条件下,在Build(项目打包)的时候Unity会自动地提取这些共享材质的静态模型的Vertex buffer和Inde ...

  6. Sentinel源码—1.使用演示和简介

    大纲 1.Sentinel流量治理框架简介 2.Sentinel源码编译及Demo演示 3.Dashboard功能介绍 4.流控规则使用演示 5.熔断规则使用演示 6.热点规则使用演示 7.授权规则使 ...

  7. 云备份技术解析:备份删除&合并原理

    本文分享自天翼云开发者社区<云备份技术解析:备份删除&合并原理>,作者:沈****军 在删除备份副本时,需要根据备份副本包含的数据块以及数据块的引用关系来进行空间的释放.当云硬盘的 ...

  8. jmeter使用之请求体包含多个数据

    在使用jmeter做压测时,除了增加并发数,还可能在请求体中增加多个字段相同的list.如图: 如果是几百条可以复制粘贴,但是几千上万条复制粘贴就比较费时费力了.另外可能这些数据并不是完全相同,可能还 ...

  9. Yuque Rich Text(语雀富文本编辑器)

    Yuque Rich Text(语雀富文本编辑器) 由于本人觉得语雀编辑器非常好用,很符合我的使用习惯,然后发现语雀的Chrome浏览器插件实现了编辑器的功能,所以将其富文本的功能拆分位一个单独的Vu ...

  10. element-ui $prompt输入弹框和$confirm确认弹框用法--输入框默认值、校验、阻止关闭等问题

    可输入弹框 $prompt 1.默认值.校验 this.$prompt( '请输入文件夹名称:', '提示', { confirmButtonText: '确定', cancelButtonText: ...