神奇的 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. [第四章]ABAQUS CM插件中文手册

    ABAQUS Composite Modeler User Manual(zh-CN) Dassault Systèmes, 2018 注: 源文档的交叉引用链接,本文无效 有些语句英文表达更易理解, ...

  2. mysql -- 自定义函数及循环结构

    和存储过程类似,区别在于存储过程可以有0个或多个返回,但是函数只能有唯一一个返回值 一般而言,存储过程适合批量插入,批量删除,增删改:函数则用于处理数据,查询某个值. 创建 create functi ...

  3. MySQL 中 DATETIME 和 TIMESTAMP 时间类型的区别及使用场景

    MySQL的日期类型简介 在 MySQL 中有两种存储时间的数据类型 DATETIME 和 TIMESTAMP,它们在数据库实际应用中,各有各的优势和劣势. 一. DATETIME 和 TIMESTA ...

  4. goland无法识别包

    新建 Go 项目时,一定要通过 "File -> New -> Project..." 方式建立,千万不要通过 "File -> Open", ...

  5. DEV插件--Spreadsheet1电子表格

    常用操作Spreadsheet常用属性标题栏是否可见 Spreadsheet1.TitleBar.Visible=true标题栏背景颜色 Spreadsheet1.TitleBar.Interior. ...

  6. elk收集分析nginx日志,并绘制图形

    一.修改nginx配置 把nginx日志修改成json格式,在nginx.conf中添加如下内容,重启nginx. log_format log_json '{"@timestamp&quo ...

  7. 【DXP】如何在原理图中批量修改

    零.问题 想要修改所有电阻的封装,怎么解决? 一.解决 以修改所有电阻封装为例,可举一反三. 在电阻上右键,选择"查找相似对象". 注意在右键的时候鼠标应该是放在元器件图标上的,而 ...

  8. Dify开发必备:分享8个官方文档不曾解释的关键技巧

    Dify 是一个帮助你快速搭建 AI 应用的工具,其定位类似Coze.但相比Coze--Dify是免费的.开源的,人人都可以用.哪怕你不懂编程,也能用它参与到 AI 应用的设计和使用中.总之,如果你是 ...

  9. java泛型简单入门

    泛型 泛型 泛指某一种类型 ( 必须是 引用类型 ) 明确时机: 1.有时候 创建对象的时候, 明确泛型 2.有时候 调用一个方法时, 明确泛型 3.有时候 创建一个类型,然后实现一个接口的时候 明确 ...

  10. 解决chrome浏览器拓展插件颜色变成透明无法使用。

    虚拟机装了chrome之后插件变成了透明的,没办法使用了. 解决办法如下: 1.卸载VMWARE tools 2.地址栏输入: chrome://flags 找到 "Choose ANGLE ...