Ison Lee

vuePress-theme-reco Ison Lee    2019 - 2020
Ison Lee Ison Lee
Home
Category
  • 前端
Tag
TimeLine
Contact
  • 掘金
  • GitHub
author-avatar

Ison Lee

5

Article

3

Tag

Home
Category
  • 前端
Tag
TimeLine
Contact
  • 掘金
  • GitHub

流程控制语句:选择结构(if/switch)

vuePress-theme-reco Ison Lee    2019 - 2020

流程控制语句:选择结构(if/switch)

Ison Lee 2020-08-07 14:33:25 JavaScript基础

# 代码块


用 {} 包围起来的代码,就是代码块。

在ES5中,代码块只有 分组 作用,代码块中的内容,外部完全可见。

{
    let a = 2;
}

console.log(`a = ${a}`);//a = 2
1
2
3
4
5

虽然变量a定义在代码块中,但是外部依然可以访问


# 流程控制语句


在一个程序执行的过程中,各条语句的执行顺序对程序的结果是有直接影响的。所以,我们必须清楚每条语句的执行流程。而且,很多时候我们要通过控制语句的执行顺序来实现我们要完成的功能。

# 流程控制语句分类

  • 顺序结构

  • 选择结构 if,switch

  • 循环结构 while,for


# 顺序结构


按照代码的先后顺序,依次执行。
结构图:


# if 语句


# 条件判断语句

条件成立才执行。如果条件不成立,那就什么都不做。

if (条件表达式) {
    //条件成立,执行内容
}
1
2
3

# 条件分支语句

  • 格式一
if (条件表达式) {
   // 条件为真时,做的事情

} else {
   // 条件为假时,做的事情

}
1
2
3
4
5
6
7
  • 格式二
if (条件表达式1) {
    // 条件1为真时,做的事情

} else if (条件表达式2) {
    // 条件1不满足,条件2满足时,做的事情

} else if (条件表达式3) {
    // 条件1、2不满足,条件3满足时,做的事情

} else {
    // 条件1、2、3都不满足时,做的事情
}
1
2
3
4
5
6
7
8
9
10
11
12

以上所有的语句体中,只执行其中一个

# 嵌套

我们通过下面这个例子来引出 if 语句的嵌套。

一个加油站为了鼓励车主多加油,所以加的多有优惠。 92号汽油,每升6元;如果大于等于20升,那么每升5.9; 97号汽油,每升7元;如果大于等于30升,那么每升6.95 编写JS程序,用户输入自己的汽油编号,然后输入自己加多少升,弹出价格。

//用户输入
 let userInputCode = parseInt(prompt('请输入油的编码。填写92或者97'))

 let userInputCapacity = parseInt(prompt('您想加多少升?'))

  let price = 0;

 if (userInputCode == 92) {
    //编号是92的时候做的事情
    if (userInputCapacity >= 20) {
         price = userInputCapacity * 5.9;
    } else {
         price = userInputCapacity * 6;
    }
} else if (userInputCode == 97) {
    //编号是97的时候做的事情
    if (userInputCapacity >= 30) {
         price = userInputCapacity * 6.95;
    } else {
         price = userInputCapacity * 7;
    }
} else {
    alert('不好意思,没有这个编号的汽油!');
}

alert('价格是' + price);

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

# switch语句


switch语句也叫条件分支语句

语法

switch(表达式) {
    case 值1:
        语句体1
        break
    case 值1:
        语句体1
        break   
        ...
    default:
        语句体 n+1
        break
}
1
2
3
4
5
6
7
8
9
10
11
12

# switch语句执行流程

  • 首先,计算出表达式的值,依次与case比较,一旦有对应的值,就会执行相应的语句,在执行过程中,遇到break就会结束。
  • 然后如果所有case和表达式的值不匹配,就会执行default语句体

# switch 和 case后面的值

switch 后面的括号里可以是表达式或者值, 通常是一个变量(通常做法是:先把表达式或者值存放到变量中)。

JS 是属于弱类型语言,case 后面的值1、值2可以是 'a'、6、true 等任意数据类型的值,也可以是表达式。注意,在这里,字符串'6'和 数字 6 是不一样的。

let msg = 'notice';

switch (msg) {
    case 'notice':
        console.log('提示');
        break;
    case 'warning':
        console.log('警告');
        break;
    case 'error':
        console.log('错误');
        break;
    default:
        console.log('默认文案');
        break;
}

let age = 28;

switch (true) {
    case age < 18:
        console.log('未成年人');
        break;
    case age >= 18 && age <= 35:
        console.log('还能干活儿');
        break;
    case age > 35:
        console.log('该退休了');
        break;
    default:
        console.log('默认文案');
        break;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

# switch 语句的结束条件

  • 遇到break结束
  • 执行到程序末尾

# case 穿透

switch 语句中的break可以省略,但一般不建议(对于新手而言)。否则结果可能不是你想要的,会出现一个现象:case 穿透

//switch判断语句
let number = 5;

switch (number) {
    default:
        console.log('我是defaul语句');
    // break;
    case 2:
        console.log('第二个呵呵:' + number);
    //break;
    case 3:
        console.log('第三个呵呵:' + number);
        break;
    case 4:
        console.log('第四个呵呵:' + number);
        break;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

# switch语句实战举例:替换if语句

我们实战开发中,经常需要根据接口的返回码 retCode ,来让前端做不同的展示。

这种场景是业务开发中经常出现的,请一定要掌握。然而,很多人估计会这么写:

# 写法一(不推荐)

let retCode = 1003; // 返回码 retCode 的值可能有很多种情况

if (retCode == 0) {
    alert('接口联调成功');
} else if (retCode == 101) {
    alert('活动不存在');
} else if (retCode == 103) {
    alert('活动未开始');
} else if (retCode == 104) {
    alert('活动已结束');
} else if (retCode == 1001) {
    alert('参数错误');
} else if (retCode == 1002) {
    alert('接口频率限制');
} else if (retCode == 1003) {
    alert('未登录');
} else if (retCode == 1004) {
    alert('(风控用户)提示 活动太火爆啦~军万马都在挤,请稍后再试');
} else {
    // 其他异常返回码
    alert('系统君失联了,请稍候再试');
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

嵌套太深,可读性很差

# 写法二 (推荐)

let retCode = 1003; // 返回码 retCode 的值可能有很多种情况
handleRetCode(retCode);

// 方法:根据接口不同的返回码,处理前端不同的显示状态
function handleRetCode(retCode) {
    if (retCode == 0) {
        alert('接口联调成功');
        return;
    }

    if (retCode == 101) {
        alert('活动不存在');
        return;
    }

    if (retCode == 103) {
        alert('活动未开始');
        return;
    }

    if (retCode == 104) {
        alert('活动已结束');
        return;
    }

    if (retCode == 1001) {
        alert('参数错误');
        return;
    }

    if (retCode == 1002) {
        alert('接口频率限制');
        return;
    }

    if (retCode == 1003) {
        alert('未登录');
        return;
    }

    if (retCode == 1004) {
        alert('(风控用户)提示 活动太火爆啦~军万马都在挤,请稍后再试');
        return;
    }

    // 其他异常返回码
    alert('系统君失联了,请稍候再试');
    return;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49

通过return改良方法一,直接通过 return 的方式,让 function 里的代码不再继续往下走,这就达到目的了。对了,因为要用到 return ,所以需要单独封装到一个 function 里面

# 写法三(推荐)


let retCode = 1003; // 返回码 retCode 的值可能有很多种情况

switch (retCode) {
    case 0:
        alert('接口联调成功');
        break;
    case 101:
        alert('活动不存在');
        break;

    case 103:
        alert('活动未开始');
        break;

    case 104:
        alert('活动已结束');
        break;

    case 1001:
        alert('参数错误');
        break;

    case 1002:
        alert('接口频率限制');
        break;

    case 1003:
        alert('未登录');
        break;

    case 1004:
        alert('(风控用户)提示 活动太火爆啦~军万马都在挤,请稍后再试');
        break;

    // 其他异常返回码
    default:
        alert('系统君失联了,请稍候再试');
        break;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40

在实战开发中,方式 3 是非常推荐的写法,甚至比方式 2 还要好。我们尽量不要写太多的 if 语句,避免代码嵌套过深。

# switch 语句的优雅写法:适时地去掉 break

错误演示:

let day = 2;

switch (day) {
    case 1:
        console.log('work');
        break;

    case 2:
        console.log('work');
        break;

    case 3:
        console.log('work');
        break;

    case 4:
        console.log('work');
        break;

    case 5:
        console.log('work');
        break;

    case 6:
        console.log('relax');
        break;

    case 7:
        console.log('relax');
        break;

    default:
        break;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34

实战开发中,凡是有重复的地方,我们都必须要想办法简化。写代码就是在不断重构的过程

正确演示:

let day = 2;

switch (day) {
    case 1:
    case 2:
    case 3:
    case 4:
    case 5:
        console.log('work');
        break; // 在这里放一个 break

    case 6:
    case 7:
        console.log('relax');
        break; // 在这里放一个 break

    default:
        break;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

# for 循环


语法:

for (①初始化表达式; ②条件表达式; ④更新表达式) {
        ③执行语句
}

for (let i = 1; i <= 100; i++) {
    console.log(i);
}
1
2
3
4
5
6
7

执行流程:

  1. 执行初始化表达式,初始化变量(只执行一次)
  2. 执行条件表达式
    • 如果为true,则执行执行语句
    • 如果为false,则终止循环
  3. 执行更新表达式,更新表达式执行完毕重新执行条件表达式

# while 循环语句


# while循环

语法:


while(条件表达式){
	语句...
}

1
2
3
4
5

执行流程:

  1. 先对条件表达式进行求值判断
    • true,执行循环体
      • 循环体执行完毕之后,继续对表达式进行判断,以此类推
    • false,终止循环

# do...while循环

语法:

do{
    语句...
} while(条件表达式)
1
2
3

执行流程:

  1. 先执行循环体
  2. 然后判断条件表达式
    • true,继续执行循环体,判断条件表达式,以此类推
    • false,终止循环

# while 和 do...while 区别

  • while是先判断再执行,do...while是先执行后判断

也就是说,do...while至少可以保证一次执行


# break 和 continue

# break

  • break 可以用来退出 switch 语句或退出整个循环语句(循环语句包括 for 循环、while 循环。不包括 if。if 里不能用 break 和 continue,否则会报错)

  • break 会立即终止离它最近的那个循环语句

  • 可以为循环语句创建一个 label,来标识当前的循环(格式:label:循环语句)。使用 break 语句时,可以在 break 后跟着一个 label,这样 break 将会结束指定的循环,而不是最近的

//break
for (var i = 0; i < 5; i++) {
    console.log('i的值:' + i);
    if (i == 2) {
        break; // 注意,虽然在 if 里 使用了 break,但这里的 break 是服务于外面的 for 循环。
    }
}

  /*      
i的值:0
i的值:1
i的值:2
 */

//continue
for (var i = 0; i < 10; i++) {
    if (i % 2 == 0) {
        continue;
    }
    console.log('i的值:' + i);
}

  /*     i的值: 1

        i的值: 3

        i的值: 5

        i的值: 7

        i的值: 9 */


//label
outer: for (var i = 0; i < 5; i++) {
    console.log('外层循环 i 的值:' + i);
    for (var j = 0; j < 5; j++) {
        break outer; // 直接跳出outer所在的外层循环(这个outer是我自定义的label)
        console.log('内层循环 j 的值:' + j);
    }
}
//外层循环 i 的值:0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42