一、循环语句的概念
1、循环语句,声明一组要反复执行的命令,直到满足某些条件为止。
2、循环包括测试条件以及一个块(通常就是 { .. })。循环块的每次执行被称为一个迭代。
二、循环语句的种类
1、while语句
概念
while 语句是一种先测试循环语句,即先检测退出条件,再执行循环体内的代码。因此,while 循环体内的代码有可能不会执行。
语法
while(expression) statement
实例
let i = 0;
while (i < 10) {
i += 2;
}
在这个例子中,变量 i 从 0 开始,每次循环递增 2。只要 i 小于 10,循环就会继续。
2、do-while语句
概念
do-while 语句是一种后测试循环语句,即循环体中的代码执行后才会对退出条件进行求值。换句话说,循环体内的代码至少执行一次。
语法
do {
statement
} while (expression);
实例
let i = 0;
do {
i += 2;
} while (i < 10);
在这个例子中,只要 i 小于 10,循环就会重复执行。i 从 0 开始,每次循环递增 2。
3、for语句
概念
for 语句也是先测试语句,只不过增加了进入循环之前的初始化代码,以及循环执行后要执行的表达式。
语法
for (initialization; expression; post-loop-expression) statement
实例
let count = 10;
for (let i = 0; i < count; i++) {
console.log(i);
}
以上代码在循环开始前定义了变量 i 的初始值为 0。然后求值条件表达式,如果求值结果为** true**(i < count),则执行循环体。因此循环体也可能不会被执行。如果循环体被执行了,则循环后表达式也会执行,以便递增变量 i。
三、注意
1、在 for 循环的初始化代码中,其实是可以不使用变量声明关键字的。不过,初始化定义的迭代器变量在循环执行完成后几乎不可能再用到了。因此,最清晰的写法是使用 let 声明迭代器变量,这样就可以将这个变量的作用域限定在循环中。
2、初始化、条件表达式和循环后表达式都不是必需的。因此,可以创建一个无穷循环如下:
for (;;) { // 无穷循环
doSomething();
}
3、如果只包含条件表达式,那么 for 循环实际上就变成了 while 循环。如下:
let count = 10;
let i = 0;
for (; i < count; ) {
console.log(i);
i++;
}
4、do-while循环和while循环很相似。区别是在while循环里,先进行条件判断再执行循环体中的代码,而在do-while循环里,是先执行循环体中的代码再判断循环条件。do-while循环至少会让循环体中的代码执行一次。
5、循环语句皆可互相嵌套,但避免嵌套多层。
四、break和continue语句
1、作用
break 和 continue 语句为执行循环代码提供了更严格的控制手段。其中,break 语句用于立即退出循环,强制执行循环后的下一条语句。而 continue 语句也用于立即退出循环,但会再次从循环顶部开始执行。
2、实例
let num = 0;
for (let i = 1; i < 10; i++) {
if (i % 5 == 0) {
break;
}
num++;
}
console.log(num); // 4
如果将 break 换成 continue,则会出现不同的效果:
let num = 0;
for (let i = 1; i < 10; i++) {
if (i % 5 == 0) {
continue;
}
num++;
}
console.log(num); // 8
3、区别
1、break 语句可以立即退出循环,阻止再次反复执行任何代码。而 continue 语句只是退出当前循环,根据控制表达式还允许继续进行下一次循环。
2、break可以用于switch语句和循环语句中,而continue只能用于循环语句中。
五、循环语句的时间复杂度
1、时间复杂度定义
时间复杂度不代表代码执行的时间,算法的时间复杂度说的是一个算法的执行时间根据规模增长的一个趋势,而并不是代码执行的具体时间。
2、常见的时间复杂度
3、时间复杂度实例
常数阶
var sum = 0;
for(var i=0;i<100;i++) {
sum += i;
}
虽然有这么多行,即使 for 循环执行了 100 次,但是代码的执行时间不随 n 的增大而增长,所以这样的代码复杂度就为 O(1)。
线性阶
for(let i = 0;i < n; i++){
let j = i;
j++;
}
这段代码在执行时,for循环里面的代码会执行n次,所以它消耗的时间会随着n的变化而变化,这样的代码都可以用O(n)来表示。
对数阶
let i = 1;
while(i < n) {
i = i * 2;
}
这段代码在执行时,while循环里面,每次都将 i * 2 ,乘完之后, i 会距离 n 越来越近,一直到 i 大于 n 为止。这样的代码都可以用O(logN)来表示。
线性对数阶
for(let k = 0; k < n; k++) {
let i = 1;
while(i < n) {
i = i * 2;
}
}
线性对数阶O(nlogN) 其实非常容易理解,将时间复杂度为O(logn)的代码循环N遍的话,那么它的时间复杂度就是 n * O(logN),也就是了O(nlogN)。
平方阶乘
for(let i = 0; i < n; i++) {
for(let i = 1; i < n; i++) {
let j = i;
j++;
}
}
平方阶O(n²) 就更容易理解了,如果把 O(n) 的代码再嵌套循环一遍,它的时间复杂度就是 O(n²) 了。