控制语句
- while/do...while 语句
- while 语句:
- do...while 语句:
- 两者的区别
- 无限循环
- for 语句
- 普通的 for 循环
- for...in 循环
- for...of 循环
- 循环过程:跳出/跳过
- 跳出
- 跳过
- 循环嵌套
- 扩展延申:做一次杠精
当前 控制语句 章节主要介绍 循环:for、while 的使用。
while/do…while 语句
while
和 do...while
是 JavaScript 中两种常用的循环语句,它们用于重复执行代码块直到指定条件不再满足为止。
while 语句:
while
语句首先检查指定的条件是否为真,如果条件为真,则执行代码块,然后重复这个过程直到条件为假为止。- 语法结构为:
while (condition) { // 执行的代码块 }
- 示例:
let count = 0; while (count < 5) { console.log(count); count++; }
do…while 语句:
do...while
语句与while
语句类似,不同之处在于它先执行代码块,然后再检查条件是否为真。这意味着即使条件初始时为假,代码块至少会被执行一次。- 语法结构为:
do { // 执行的代码块 } while (condition);
- 示例:
let count = 0; do { console.log(count); count++; } while (count < 5);
这两种循环语句都有自己的用途,你可以根据具体情况选择合适的循环结构来完成任务。
两者的区别
while
和 do...while
之间的主要区别在于它们对条件的检查时间:
-
while
语句:- 在
while
语句中,首先检查条件是否为真,如果条件为假,则代码块不会被执行。 - 如果条件初始时就为假,代码块将完全不会执行。
- 在
-
do...while
语句:- 在
do...while
语句中,首先执行一次代码块,然后再检查条件是否为真。 - 即使条件初始时为假,代码块至少会被执行一次。
- 在
因此,do...while
适用于需要至少执行一次代码块的情况,而 while
则更适用于只在条件为真时才执行代码块的情况。
如下示例-(来演示 while
和 do...while
循环之间的区别):
示例 1:使用 while
循环
let count1 = 0;
while (count1 < 5) {
console.log("while 循环: ", count1);
count1++;
}
在这个示例中,while
循环首先检查条件 count1 < 5
是否为真。如果初始时 count1
的值已经大于或等于 5,那么代码块将根本不会执行。只有在条件为真时,即 count1
的值小于 5 时,代码块才会被执行。
示例 2:使用 do...while
循环
let count2 = 0;
do {
console.log("do...while 循环: ", count2);
count2++;
} while (count2 < 5);
在这个示例中,do...while
循环首先执行一次代码块,然后再检查条件 count2 < 5
是否为真。即使初始时 count2
的值大于或等于 5,代码块也至少会被执行一次。
示例说明:
假设 初始时
count1
和count2
的值都是 5,那么在while
循环中,代码块根本不会执行,因为条件不满足。而在do...while
循环中,代码块会被执行一次,然后检查条件,发现条件不满足,循环结束。
因此,do...while
循环适用于需要至少执行一次代码块的情况,而 while
循环则更适用于只在条件为真时才执行代码块的情况。
无限循环
Q
:什么是无限循环?
A
:永远不会结束(条件表达式结果不为 False)的循环称为无限循环。
// condition 这个表达式 结果不为 False,将会无限循环
while (condition) {
// 执行的代码块
}
do {
// 执行的代码块
} while (condition); // condition 这个表达式 结果不为 False,将会无限循环
下面是一个无限循环的示例,使用 while 循环:
while (true) {
console.log("这是一个无限循环!");
}
在这个示例中,循环条件始终为 true,因此循环将无限执行下去,打印出 “这是一个无限循环!”
的消息。由于循环条件永远为真,程序将永远无法跳出循环,除非手动停止执行或发生错误。
注意
:
- 无限循环会给 浏览器 带来极大的负荷,甚至导致死机。所以,在写循环处理之前,首先要确认循环是否能正常结束。
- 无限循环在某些程序中,也有可能是有意设计的,例如在某些服务程序或事件驱动的应用程序中,需要保持程序持续运行以监听事件。
for 语句
上面篇幅讲解了while/do...while
循环,当前讲解for
循环。但在此之前,先说下两者的区别?
区别:
while/do...while
是根据条件表达式的真假控制循环的。for
是根据执行指定次数控制循环的。
Q
:啥意思呢?
A
:听我慢慢给你狡辩~~~
首先,需要先知晓:在 JavaScript 中,for
循环的写法,一般有三种:普通的 for 循环、for…in 循环、for…of 循环
现在分别 一 一 介绍:
普通的 for 循环
语法格式:
for(初始值; 继续循环的条件表达式; 增减表达式) {
// 循环体:即 -> 循环内重复执行的代码。
}
例如:需求
打印 1、2、3、4
非循环代码:
console.log(1);
console.log(2);
console.log(3);
console.log(4);
上述,
console.log();
表示在浏览器控制台进行输出(即打印);需求打印的只是4个数字,直接写 4遍console.log()
能实现需求,到也没啥? 但若需求要打印 400 个数字,此时在console.log()
分别写出、反而不太现实。
此时,便可使用 for 循环(或者while等循环也行,此处介绍for循环)
使用 for 循环,打印 1、2、3、4
for(var i = 1; i <= 4; i++) {
console.log(i);
}
扩展说明
:i++
的意思,就是:i = i + 1;
程序员数数一般是从 零 开始数,所以,上面的代码示例,也可以更新如下:
for(var i = 0; i < 4; i++) {
console.log(i+1);
}
for…in 循环
当使用 for...in
循环时,它会遍历对象的可枚举属性,并对每个属性执行指定的操作。
语法格式:
for (variable in object) {
// 循环体
}
什么是 对象? 后面章节会介绍,当前若不太理解;那就先记住有for..in
这样的一种循环
下面是一个详细的例子:
// 定义一个对象
const person = {
name: '九皇叔叔',
age: 28,
city: '上海'
};
// 使用 for...in 循环遍历对象的属性
for (let key in person) {
// 检查对象是否拥有该属性,而不是原型链上的属性
if (person.hasOwnProperty(key)) {
// 打印属性名和对应的值
console.log(key + ': ' + person[key]);
}
}
在这个例子中,我们有一个名为 person
的对象,它有三个属性:name
、age
和 city
。然后,我们使用 for...in
循环遍历了 person
对象的属性。在循环的每次迭代中,key
变量将被赋值为对象的一个属性名。我们使用 hasOwnProperty
方法来确保属性确实属于对象本身,而不是继承自原型链。
在循环的每次迭代中,我们打印属性名和对应的值。输出将会是:
name: 九皇叔叔
age: 28
city: 上海
这就是 for...in
循环,它非常适用于遍历对象的属性。
需要注意的是:for...in
循环不会按照属性的顺序进行遍历,而且它会遍历对象的所有可枚举属性,包括从原型链继承而来的属性。因此,在处理对象属性时,需要谨慎使用,并且结合 hasOwnProperty
方法来过滤出对象本身的属性。
for…of 循环
for...of
循环用于遍历可迭代对象(例如数组、字符串、Map、Set 等),并对其中的每个元素执行指定的操作。
语法格式:
for (variable of iterable) {
// 循环体
}
其中:
variable
:在每次迭代中,variable
会被赋值为可迭代对象中的当前元素。这是一个变量,用于引用当前迭代的元素。iterable
:表示一个可迭代对象,例如数组、字符串、Map、Set 等。
在 for...of
循环中,variable
将会依次取得 iterable
中的每个元素,并且循环体会针对每个元素执行一次。这使得 for...of
循环非常适合用于遍历可迭代对象中的元素,并且相对于普通的 for
循环来说,更加简洁易读。`
下面是一个示例:
// 定义一个数组
const arr = [1, 2, 3];
// 使用 for...of 循环遍历数组
for (let value of arr) {
console.log(value);
}
在这个例子中,我们有一个名为 arr
的数组,包含了几个整数。然后,我们使用 for...of
循环遍历了数组 arr
中的每个元素。在循环的每次迭代中,value
变量将被赋值为数组的一个元素值。
在循环的每次迭代中,我们打印了 value
的值。输出将会是:
1
2
3
这就是 for...of
循环的详细示例。它提供了一种简洁的方式来遍历可迭代对象中的元素,并且与传统的 for
循环相比,不需要索引或者额外的索引变量,使代码更加清晰易读。需要注意的是,for...of
循环仅遍历可迭代对象的元素值,而不会遍历对象的属性。
扩展 思考:上述的
for ... of
示例,可否使用普通的 for 循环
实现??
肯定是可行的,代码如下:
// 定义一个数组
const arr = [1, 2, 3];
// 使用普通的 for 循环遍历数组
for (let i = 0; i < arr.length; i++) {
// 获取数组的每个元素
const value = arr[i];
console.log(value);
}
至此,三种 for 循环的方式,也就介绍完了。
回过头来,看最初的问题:
区别:
while/do...while
是根据 条件表达式的真假 控制循环的。for
是根据 执行指定次数 控制循环的。
Q
:啥意思呢?
现在以 需求示例
:计算 1+2+…+100 的结果是多少?进行解答啥意思?
while 循环的方式,实现需求,代码如下:
let sum = 0;
let i = 1;
// 看这里,i <= 100 这个结果只有两种可能:True 或者 False
// True: 真, False:假
// `while/do...while` 是根据 **条件表达式的真假** 控制循环的。
while (i <= 100) {
sum += i;
i++;
}
console.log('从1加到100的和为:' + sum);
for 循环的方式,实现需求,代码如下:
let sum = 0;
// 看这里,是一个循环的次数;
// `for` 是根据 **执行指定次数** 控制循环的。
for (let i = 1; i <= 100; i++) {
sum += i;
}
console.log('从1加到100的和为:' + sum);
至此,啥意思呢? 介绍结束了,也没啥意思。
循环过程:跳出/跳过
无论是 while
还是 for
在循环的过程中,都是可以进行 跳出/跳过
跳出:就是终止当前循环的意思。
跳过:就是跳过当前迭代,继续执行下一次迭代,直至整个循环结束。
跳出
使用 break
关键字可以在循环中跳出循环,停止循环的执行。
// 使用 for 循环来查找数组中的某个特定元素,并在找到时跳出循环
const arr = [1, 2, 3, 4, 5, 6];
const target = 4;
let found = false;
for (let i = 0; i < arr.length; i++) {
if (arr[i] === target) {
found = true;
break; // 当找到目标元素时,跳出循环
}
}
console.log(found ? "找到了目标元素" : "未找到目标元素");
在这个例子中,我们遍历数组 arr
,如果找到了目标元素 target
,则将 found
设置为 true
,并且使用 break
关键字跳出循环。这样,当找到目标元素时,循环将停止执行。
跳过
使用 continue
关键字可以跳过当前循环的某次迭代。
// 使用 for 循环打印数组中的奇数,并跳过偶数
const arr = [1, 2, 3, 4, 5, 6];
for (let i = 0; i < arr.length; i++) {
if (arr[i] % 2 === 0) {
continue; // 如果当前元素是偶数,则跳过本次循环迭代
}
console.log(arr[i]);
}
在这个例子中,我们遍历数组 arr
,如果当前元素是偶数,则使用 continue
关键字跳过本次循环迭代,直接进行下一次迭代。这样,只有奇数才会被打印出来。
这就是在 JavaScript 中使用 break
和 continue
实现跳出循环和跳过当前迭代的使用。这两个关键字可以帮助我们更加灵活地控制循环的执行流程。
循环嵌套
循环嵌套就是:循环里面嵌套循环。
可以是while
里面嵌套while
,也可以 while
里面嵌套 for
循环 等等情况;当然也可以嵌套很多层,不过一般 不超过3层。
例如,打印 九九乘法口诀表
while
循环方法,实现:
// 使用 while 循环打印乘法口诀表
let i = 1;
while (i <= 9) {
let row = '';
let j = 1;
while (j <= i) {
row += `${j} * ${i} = ${i * j}\t`;
j++;
}
console.log(row);
i++;
}
此外,
还可以使用 for
循环方法,实现:
// 使用 for 循环打印乘法口诀表
for (let i = 1; i <= 9; i++) {
let row = '';
for (let j = 1; j <= i; j++) {
row += `${j} * ${i} = ${i * j}\t`;
}
console.log(row);
}
扩展说明
循环嵌套:跳出
如下:
【A】for(var i = 0; i < 100; i++) {
【B】for(var j = 0; j < 100; j++) {
【C】for(var k = 0; k < 100; k++) {
// 这里面有好多..好多代码...
break;
}
}
}
注意
- 上述的代码中,
break
只能跳出(或终止)【C】处的for
循环,不能跳出【A】、【B】两处的for
循环。- 若将
break
换成continue
也是如此意思(即只能对【C】处的for
循环有作用)。
扩展延申:做一次杠精
扩展延申,主要是延申:for
循环;
杠精呢,我们主要杠:for ... in
和 for ... of
当时举例讲解 for 循环
时,便说明了:
for ... in
用来遍历对象;for ... of
用来遍历数组;
那,能不能用 for...in
来遍历 数组 呢??
在回答问题之前,先看下:对象、数组;
如何创建对象?数组?
// 创建一个对象,
// 当然也可以使用语法糖方式创建对象:var client = {...};
var client = new Object();
client['name'] = '九皇叔叔';
client['age'] = 28;
// 创建一个数组,
// 当然也可以使用语法糖方式创建数组:var tangGuo = ['1颗糖', '2颗糖', '3颗糖'];
var tangGuo = new Array(3); // 创建一个长度为3的空数组
tangGuo[0] = '1颗糖';
tangGuo[1] = '2颗糖';
tangGuo[2] = '3颗糖';
现在呢,我 篇要用、我 就要用 for...in
来遍历数组:
for (let index in tangGuo) {
console.log(`索引 ${index} 对应的值为:${tangGuo[index]}`);
}
在浏览器的控制台中 => 运行结果如下:
看着没啥问题,是吧。
但是呢,不建议:你这么做(使用for...in
变量 数组)
用大白话解释一下:
假如你有女朋友(虽然我也没有),
- 那在结婚之前呢,一般称呼是:宝宝;(电视上看的)。
- 那结婚之后呢,一般称呼是媳妇。(也是电视上看的)。
但是呢,你非要杠:结婚之前,就是要喊 媳妇。
那,就是要喊 媳妇
行不行呀
??
- -----
也行
,但是:不建议你这么喊。- 万一 被你七大姑八大姨听到了,她们就会很诧异:你媳妇??你小子、这是啥时候结的婚呀??怎么还不给我们说一声呀??我这份子钱都准备好了、哎呀呀~~太把我们当外人了…(发生了一些预期之外的事情)
就像我们的程序一样,若使用for...in
遍历数组,也万一 一不小心会 发生了一些预期之外的事情
例如:
在实际开发代码时,会写很多很多代码(扩充功能的呀等等),就像下面这样,使用原型扩充了一个炫耀糖果的方法:
Array.propertype.xuanyao = function() {
return '我有好多好多~糖果!!!';
}
浏览器控制台-执行代码后,输出如下(没有报错,说明方法扩充成功了):
然后,在次使用 for...in
打印一下,
在打印之前,我们做一个预期:
预期打印的结果还是之前一样(如下):不会输出扩充方法。
但是,
实际上:
浏览器控制台输出结果如下:(发生了一些预期之外的事情)。假若扩充了10个方法 那也是会打印出来10个的。
那这个时候,
在使用for...of
进行打印呢?符合预期:没有输出扩充的方法
综上,
- 当使用
for...in
循环时,它会遍历对象的 可枚举属性,并对每个属性执行指定的操作。 for...of
循环用于遍历 可迭代对象(例如数组、字符串、Map、Set 等),并对其中的每个元素执行指定的操作。- 不建议使用
for...in
循环 遍历 可迭代对象(例如数组、字符串、Map、Set 等)。