跳转至

循环

循环 是编程语言常见的一种流程控制。

所谓循环 就是反复的执行一段代码。

我们人类语言要让别人反复的做一些事,可以这样说: 请你一直怎样怎样,或者请你反复怎样怎样。

js语言要让计算机反复的做一些事 就要使用循环语句。

js 中有3种类型的循环: while循环do while循环for 循环

while 循环

while循环 是:

检查一个条件表达式,只要条件表达式计算结果为 true 时, 就执行花括号中的代码。

如此反复,直到条件表达式计算结果为 false 时,结束 循环。

比如:

var command = prompt("请输入命令")
while (command !== 'exit'){
    alert(`输入的命令是${command}`)
    command = prompt("请输入命令")
    // 下面可以写执行命令的代码
}    

其中 while command != 'exit' 会判断用户输入的命令 (command 变量) 是否等于字符串 exit

如果不等于, 就执行下面缩进的代码。下面缩进的代码就是循环体内的代码,还会再次让用户输入命令到变量command中。

如果等于字符串 exit, 就结束循环。

如果用户输入的命令一直都不是字符串 exit , 就会一直执行循环。

大家可以运行一下看看。


用 while 循环要注意 循环条件的设置,处理不当,有可能导致 循环的条件始终为true,循环永远不会结束,变成了死循环。

比如,我们要打印出 从 1 到 10 的数字,应该写成下面这样

var i = 1
while (i <= 10){
    console.log(i)
    i++
}

如果不小心,漏掉最后一句,变成

var i = 1
while (i <= 10){
    console.log(i)
}

这样 i 的值始终不变, 循环的条件 i <= 10 一直都是满足的,就变成死循环了。程序一直打印 i 值为 1 ,永不结束。

do while循环

上面的示例中

var command = prompt("请输入命令")
while (command !== 'exit'){
    alert(`输入的命令是${command}`)
    command = prompt("请输入命令")
}    

我们发现 command = prompt("请输入命令") 这行代码写了两遍。

因为 变量 command 在 while 循环前必须有个值,循环里面也需要重新得到用户输入值。

这种情况,可以使用 do while 循环

如下

do {
    command = prompt("请输入命令")
    alert(`输入的命令是${command}`)
}    while (command !== 'exit')

代码更精简。

do while 循环 肯定要先执行一次循环体内代码, 然后再判断是否继续循环的条件。

而 while 循环 是 一开始就要先判断循环条件是否成立, 成立后再执行循环体代码。

大家根据实际需要,灵活选用。

for 循环

循环 n 次

for 循环更适合 循环执行某段代码 指定次数

比如,我们要打印出 从 1 到 10 的数字

for (var i=1; i<=10; i++) {
  console.log(i)
}


注意:

for 循环的 后面那个括号里面有3个语句组成

for (循环前执行代码; 循环继续与否判定表达式; 单次循环后执行代码) {
  // 循环体代码
}

其中

  • 循环前执行代码

是 整个 for循环前 要执行的代码,只执行1次。

常用于 定义循环次数标记变量

  • 循环继续与否判定表达式

是 每次循环前用来判定是否继续执行本次循环的 表达式。

如果 表达式结果为true 执行本次循环, 如果 为 false 结束整个for循环

  • 单次循环后执行代码

是 每次循环后 要执行的一次语句

常用来执行 循环次数标记变量 的值变化

遍历数组

可以这样遍历数组,使用 for ... of 写法

let colors = ['red', 'green', 'blue'];
for (const color of colors){
    console.log(color);
}

或者,也可以使用原来的方法

var myStringArray = ["Hello","World"];
var arrayLength = myStringArray.length;
for (var i = 0; i < arrayLength; i++) {
    console.log(myStringArray[i]);
    //Do something
}

详见视频讲解里面的说明


for 循环 经常用于遍历数组,比如 从 数组中 依次取出每个元素进行操作。

比如,我要打印出 一个学生年龄 数组中所有的学生信息

可以这样写

const studentAges = ['小王:17', '小赵:16', '小李:17', '小孙:16', '小徐:18']

for (var i = 0; i < studentAges.length; i++) {
    console.log(studentAges[i])
}

ES6 以后,js 还支持更简单的 for ... of 写法。

这种写法适合遍历可遍历对象,比如 字符串String、数组Array、TypedArray, Map, Set 等等。

如下:

for (let student of studentAges){
    console.log(student)
}

每次循环,都会依次

  • 取出 of 后面的数组里面的对象,赋值给 of 前面定义的变量

  • 执行循环体里面的代码

这里有5个学生的信息, 那么这个循环就执行了5次。

从循环的第1次到第5次,student 变量的值分别为:

'小王:17'
'小赵:16'
'小李:17'
'小孙:16'
'小徐:18'

所以上面的循环可以依次打印出上面的元素。


当然 用while循环也一样可以遍历数组,就是稍微复杂一些

let idx = 0
while (idx < studentAges.length){
    console.log(studentAges[idx])
    idx++
}

上面的代码里,我们用一个变量idx代表 数组当前元素的索引。 在循环体里面 每执行一次就 让idx 的值加1。 这样的循环,变量 currentEle就依次等于 数组里面的每个元素。


如果循环操作一个空数组,如下

for (let student of []){
    console.log(student)
}

循环体内的代码不会执行。

遍历对象

如果我们需要遍历一个对象里面的所有属性和值,怎么办?

Object.entries 方法可以返回 对象的属性和值 到一个数组,方便我们遍历

然后使用 for ... of 遍历数组

如下:

var obj1 = {
  a: 'somestring',
  b: 42
};

// 以 obj1 为原型创建 obj2 对象
var obj2 = Object.create(obj1)
obj2.c = 33
obj2.d = 44

//  使用for ... of 遍历数组
for (let [key, value] of Object.entries(obj2)) {
  console.log(`${key}: ${value}`);
}



js 种还有一种 for ... in 循环遍历对象的方法。

但是,这种方式获取的不仅仅是对象自身的属性,还会获取 对象原型的属性

for (let key in obj2) {
  console.log(`${key}: ${obj2[key]}`);
}


如果要过滤掉原型属性,可以加一个判定条件,如下

for (let key in obj2) {
  if (obj2.hasOwnProperty(key))
    console.log(`${key}: ${obj2[key]}`);
}

因为对象的 hasOwnProperty (Object 的原型里面的)方法,可以返回这个属性是否是对象自身的属性

break 终止循环

有时,我们循环体内的代码在发现某种条件满足的时候,需要终止循环。

比如,本文开头的例子

用户输入的命令如果等于字符串 'exit' 就结束循环

当然像面那上样的代码也是可以的

var command = prompt("请输入命令")
while (command !== 'exit'){
    alert(`输入的命令是${command}`)
    command = prompt("请输入命令")
}    
console.log('程序结束')

只是,这样 代码有写啰嗦, command = input("请输入命令")写了两次。

如果不改用 do while 方式,

我们还可以使用关键字 break ,就可以这样

while (true) {
    var command = prompt("请输入命令:")
    alert(`输入的命令是${command}`)
    if (command == 'exit') break
}
console.log('程序结束')

注意,解释器执行到 循环内的 break 语句,就会从循环while 退出,

接着执行while 循环下面的代码 console.log('程序结束')


break 对 for 循环也一样有效,如下:

for (var i=1; i<=10; i++) {
    var command = prompt("请输入命令:")
    if (command == 'exit') break
    alert(`输入的命令是${command}`)
}
console.log('程序结束')

函数中的 break 和 return

很多初学者,经常会搞不清函数里面的 breakreturn 的区别。

首先, return 只能用在函数里面, 表示 从函数中返回。

代码主体部分是不能用 return 的。

比如,下面的代码执行起来就会报错

while (true) {
    var command = prompt("请输入命令:")
    alert(`输入的命令是${command}`)
    if (command == 'exit') 
        return
}

提示

Uncaught SyntaxError: Illegal return statement

因为 return 是表示从函数中返回,它 是不能用在 函数外面的。


函数中的循环体内的代码, 使用 return 和 break 都可以从循环中跳出。

但是,break 只是 跳出循环, 如果循环后面还有代码, 会进行执行,如下

function inputCommand(){

    while (true) {
        var command = prompt("请输入命令:")
        console.log(`输入的命令是${command}`)
        if (command == 'exit') 
            break
    }
    console.log('末尾语句')
}

inputCommand()

执行该函数,输入 exit 发现,还会打印出 末尾语句 这句话

return 则会从函数里面立即返回, 函数体内的后续任何代码都不执行了,我们把上面的代码中的break 换成return, 如下

function inputCommand(){

    while (true) {
        var command = prompt("请输入命令:")
        console.log(`输入的命令是${command}`)
        if (command == 'exit') 
            return
    }
    console.log('末尾语句')
}

inputCommand()

执行该函数,输入 exit 发现,就不会打印出 末尾语句 这句话

continue

有时,我们循环体内的代码在发现某种条件满足的时候,

不是要终止整个循环,

而是只结束当前这一轮循环,后面还要继续循环的执行


还是上面的例子,我们增加一个功能:

用户输入的命令如果等于字符串 'exit' 就结束程序;

而用户输入的命令如果等于字符串 'cont' 就不打印这个命令,但是还让用户继续输入下一个命令

我们可以使用关键字 continue ,就可以这样

while (true) {
    var command = prompt("请输入命令:")
    if (command === 'exit') 
        break
    else if (command === 'cont') 
        continue    
    console.log(`输入的命令是${command}`)
}

运行一下看看。

再强调一遍: continue 只是当前这次循环结束,就是这次循环 continue 后面的代码不执行了, 后续的循环还要继续进行。

break 是结束整个循环

循环嵌套

我们来看一个编程题:

下面有两个数组 分别代表 刘备 和 曹操 麾下的猛将。

var list1 = ['关羽','张飞','赵云','马超','黄忠']
var list2 = ['典韦','许褚','张辽','夏侯惇','夏侯渊']

要求大家编写一段代码,让 list1中每员大将和list2中的每员大将 都互相厮杀一次,打印出 A 大战 B。


这是典型的 2个数组元素两两组合的问题, 需要用到循环的嵌套。

所谓循环的嵌套,就是循环里面还有循环。

对应的代码如下

var list1 = ['关羽','张飞','赵云','马超','黄忠']
var list2 = ['典韦','许褚','张辽','夏侯惇','夏侯渊']

for (let member1 of list1){
    for (let member2 of list2){
        console.log(`${member1} 大战 ${member2}`)
    }
}

输出结果如下:

关羽 大战 典韦
关羽 大战 许褚
关羽 大战 张辽
关羽 大战 夏侯惇
关羽 大战 夏侯渊
张飞 大战 典韦
张飞 大战 许褚
张飞 大战 张辽
张飞 大战 夏侯惇
张飞 大战 夏侯渊
赵云 大战 典韦
赵云 大战 许褚
赵云 大战 张辽
赵云 大战 夏侯惇
赵云 大战 夏侯渊
马超 大战 典韦
马超 大战 许褚
马超 大战 张辽
马超 大战 夏侯惇
马超 大战 夏侯渊
黄忠 大战 典韦
黄忠 大战 许褚
黄忠 大战 张辽
黄忠 大战 夏侯惇
黄忠 大战 夏侯渊

您需要高效学习,找工作? 点击咨询 报名实战班

点击查看学员就业情况