神奇的 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. (附体验地址)大模型知识引擎:AI 助手能否助力销售技能提升?

    体验地址:https://lke.cloud.tencent.com/webim_exp/#/chat/FAIMcM 腾讯云的大模型知识引擎本身定位于为企业客户及合作伙伴提供服务,因此我在探索如何最佳 ...

  2. PPT 技巧&网站

    样机生成网站 https://mockuphone.com/device?type=computer CTROL+L 演示生成荧光笔 3.如何内嵌字体 文件->选项->保存->勾选潜 ...

  3. Qt 重载QComboBox,实现右侧删除键

    文章目录 Qt 重载QComboBox,实现右侧删除键 前言 方案 设置下拉箭头图标 设置QComboBox内容为空 自定义showPopup函数 定位鼠标 屏蔽鼠标右键 最终控制下拉代码 效果图 代 ...

  4. Huawei Cloud EulerOS上安装sshpass

    下载源码 git clone https://github.com/kevinburke/sshpass.git 由于网络问题,这里我用了一个代理下载 git clone https://ghprox ...

  5. Go语言fmt.Sprintf、fmt.Printf(格式化输出)

    fmt.Printf fmt.Printf在程序中使用%f来格式化所需的值 看起来我们的值被四舍五入到了一个合理的数.但小数点后仍显示了6位,这对我们当前的需要来说实在是太多了. 对于这种情况,格式化 ...

  6. AI+Web3:张三的未来机会地图

    热点风暴:ETHDenver 2025掀起热潮 滑动微信的那一刻,张三愣住了.热搜上,ETHDenver大会简直是技术圈的春晚.AI和Web3,这两个曾经高高在上的概念,突然变得触手可及.大会透露的一 ...

  7. 【JDBC第9章】Apache-DBUtils实现CRUD操作

    第9章:Apache-DBUtils实现CRUD操作 9.1 Apache-DBUtils简介 commons-dbutils 是 Apache 组织提供的一个开源 JDBC工具类库,它是对JDBC的 ...

  8. Python的日志

    Python的日志,看上去啰啰嗦嗦的.请大神写了个通俗易懂简单方便通用的日志: import logging # 配置日志记录级别和输出方式 logging.basicConfig(level=log ...

  9. Linux下安装node及npm

    Linux下安装node 1.解压 $ tar zxf node-v8.9.0-linux-x64.tar.gz 2.移动到指定目录 $ mv node-v8.9.0-linux-x64 /usr/l ...

  10. ThreadPoolExecutor的内部类Worker详细解析

    一.定义 ThreadPoolExecutor 的内部类 Worker 是线程池的核心实现之一,它封装了线程和任务,并负责执行任务.Worker 类继承自 AbstractQueuedSynchron ...