流程控制语句
条件语句
if 语句(一般和 else 一起使用)
- 表示如果...就...否则...
- 在 if 语句中,else 是可以省略的
var a = 1
if ((a = 1)) {
console.log('a=1')
}
- 如果 if 语句体中只有一行语句,可以省略大括号和换行
if (a = 1) console.log('a=1')
if...else...if 多条件分支
var score = 88
if (score >= 85) {
console.log('优秀')
} else if (score >= 70) {
console.log('良好')
} else if (score >= 60) {
console.log('及格')
} else {
console.log('不及格')
}
if 语句的嵌套
某游乐园的门票价格如下表所示。请用户输入年龄和星期几,弹出对话框显示门票价格。星期几用阿拉伯数字0、1、2、3、4、5、6表示,其中0表示周日。
年龄大于等于10岁 | 年龄小于10岁 | |
---|---|---|
平日 | 300 | 140 |
周末 | 500 | 210 |
var Price = function (age, day) {
var price = 0
if (age < 10) {
if (day == 0 || day == 6) {
price = 210
} else {
price = 140
}
} else {
if (day == 0 || day == 6) {
price = 500
} else {
price = 300
}
}
return price
}
console.log(Price(10, 1))
switch 语句
switch 语句的用途:当一个变量被分类讨论的情形
- 在 switch()的圆括号中一般是一个变量名,这个变量将被分类讨论
- case 表示“情况”,它后面没有圆括号,直接跟一个值。程序会依次将 case 后面的值与 switch 圆括号中的值进行全等比对,如果比对结果为true,则执行这条 case 冒号后面的语句
- 如果比较结果为false,则继续向下比较,如果所有的比较结果都为false,则执行default后的语句
- 多条 case 可以共用同一个语句体
var Animal = 'Giraffe';
switch (Animal) {
case 'Cow':
case 'Giraffe':
case 'Dog':
case 'Pig':
console.log('This animal will go on Noah\'s Ark.');
break;
case 'Dinosaur':
default:·
console.log('This animal will not.');
}
- switch 语句并不像 if 语句那样当执行了某一个分支之后会自动跳出 if 语句体,必须主动调用 break 来跳出 switch 语句体。如果不书写 break,则后面的所有 case 都将被视为匹配,直到遇见 break。
var foo = 0;
switch (foo) {
case -1:
console.log('negative 1');
break;
case 0: // foo 的值为 0 所以匹配这里所以这一块会运行
console.log(0);
// 注意:那个没写的 break 原本在这儿
case 1: // 'case 0:' 里没有 break 语句所以这个 case 也会运行
console.log(1);
break; // 遇到了 break,所以不会再继续进入 'case 2:' 了
case 2:
console.log(2);
break;
default:
console.log('default');
}
- switch 语句内的块级作用域ES6
const action = 'say_hello';
switch (action) {
case 'say_hello':
let message = 'hello';
console.log('0 ~5');
break;
case 'say_hi':
let message = 'hi';
case 6: console.log('6');
break;
default:
console.log('Empty action received.');
break;
}
这个示例会导致意想不到的错误 Uncaught SyntaxError: Identifier 'message' has already been declared
.
这是因为第一个 let message = 'hello';
与第二个 let message = 'hi';
语句产生了冲突,虽然他们处于各自分隔的 case 语句中,即 case 'say_hello':
和 case 'say_hi':
。导致这一问题的根本原因在于两个 let
语句处于同一个块级作用域,所以它们被认为是同一个变量名的重复声明。
通过把 case 语句包装到括号里面,我们就可以轻松解决这个问题。
const action = 'say_hello';
switch (action) {
case 'say_hello': { // added brackets
let message = 'hello';
console.log(message);
break;
} // added brackets
case 'say_hi': { // added brackets
let message = 'hi';
console.log(message);
break;
} // added brackets
default: { // added brackets
console.log('Empty action received.');
break;
} // added brackets
}
三元运算符
条件表达式?表达式 1:表达式 2
问号前面是判断的条件,问号后面用冒号隔开两个表达式。当条件表达式为真时调用表达式 1,为假时调用表达式 2。
三元运算符的用途:根据某个条件是否成立,在两个不同值中选择变量的值
var age = 18
var res = age >= 18 ? '成年人' : '未成年人'
console.log(res) // 成年人
循环语句
// TODO 1028 整理
for
for 语句的执行机理
for 循环还有一个特别之处,就是设置循环变量的那部分是一个父作用域,而循环体内部是一个单独的子作用域。
for (let i = 0; i < 3; i++) {
let i = 'abc'
console.log(i)
}
// abc
// abc
// abc
上面代码正确运行,输出了 3 次 abc。这表明函数内部的变量 i 与循环变量 i 不在同一个作用域,有各自单独的作用域(同一个作用域不可使用 let 重复声明同一个变量)。
for 循环的高级用法
语法:label : statement
①label 表示标签名
②statement 表示代码块
③label 标签名与 statement 表示代码块之间使用英文状态下的冒号分隔
定义的标签可以在将来由 break 或 continue 语句引用。
var num = 0
outernum: for (var i = 0; i < 10; i++) {
for (var j = 0; j < 10; j++) {
if (i == 5 && j == 5) {
break outernum
}
num++
}
}
alert(num) //55
在这个例子中,outernum 标签表示外部的 for 语句。如果每个循环正常执行 10 次,则 num++语句就会正常执行 100 次。换句话说,如果两个循环都自然结束,num 的值应该是 100。但内部循环中的 break 语句带了一个参数(outernum 标签)。添加这个标签的结果将导致 break 语句不仅会退出内部的 for 语句(即使用变量 j 的循环),而且也会退出外部的 for 语句(即使用变量 i 的循环)。为此,当变量 i 和 j 都等于 5 时,num 的值正好是 55。同样,continue 语句也可以像这样与 1abel 语句联用,如下面的例子所示:
var num = 0
outernum: for (var i = 0; i < 10; i++) {
for (var j = 0; j < 10; j++) {
if (i == 5 && j == 5) {
continue outernum
}
num++
}
}
alert(num) //95
在这种情况下,continue 语句会强制继续执行循环,即退出内部循环,执行外部循环。当 j 是 5 时,continue 语句执行,而这也就意味着内部循环少执行了 5 次,因此 num 的结果是 95。
while
- while 语句,是一种“不定范围”循环.
- While 语句事先不指定循环开始、结束的范围,只要测试条件满足,就一直执行循环体
- while 循环没有显式定义循环变量,必须自己在 while 循环外先定义好循环变量,有时甚至可以没有循环变量。
var n = 1
var result = 0
while (n <= 100) {
result += n
n++
}
console.log(result) // 输出1到100的和
- 循环体内的语句,必须使循环测试条件趋向不成立,否则会死循环
- 一定要注意“出一”错误 小兔子拔萝卜,第 1 天拔 1 个,第 2 天拔 2 个,第 3 天拔 3 个问:第几天能拔光 500 个萝卜?
var sum = 0
while (sum < 500) {
sum += n // 32天的时候已经拔了超过500个萝卜
n++ // 但是这条语句还会执行,导致出一错误
}
console.log(n - 1) // 所以最好要减一
break,continue
- break 表示立即终止循环,它只能用在循环语句中,在 for 循环和 while 循环中都可以使用
- break 用在 while 语句中,通常和 While(true){}搭配使用
while(true){}是一个死循环,通过 break 可以让它终止循环。
- continue 用于跳过循环中的一个迭代,并继续执行循环中的下一个迭代。
do...while
- do while 循环是一种“后测试循环语句”。它不同于 for 循环和 While 循环每次都是“先测试条件是否满足,然后执行循环体″,do- While 循环是“先执行循环体,然后测试条件是否满足
- do- while 循环将循环执行条件写到了循环体的后面,这样一来,循环体一定会至少执行一次,然后再检测循环执行条件是否为 true,决定是否继续执行循环体。
var i = 11
do {
console.log(i)
i++
} while (i <= 10)
随机数函数
Math.random()返回介于 0(包含) ~ 1(不包含) 之间的一个随机数
如果想要得到[a,b]区间的整数,公式
// 这里也可以使用Math.trunc()
Math.floor(Math.random() * (b - a + 1)) + a
eg:请编写程序,随机生成两个变量 dx 和 dy,它们均在【-4,4】 区间随机取值,但要求 dx 和 dy 不能同时为 0
var a = -4
var b = 4
do {
var x = Math.floor(Math.random() * (b - a + 1)) + a
var y = Math.floor(Math.random() * (b - a + 1)) + a
} while (x == 0 && y == 0)
console.log(x, y)
3 种循环对比
拓展案例
累加器累乘器
【某大厂面试题】圆周率 π 可以由下面的莱布尼茨级数公式计算出来,请由用户输入参数 n,计算圆周率 π
// 累加器 就是最后的答案
var sum = 0
// 累乘器,用于制作每一项,制作出来的每一项,往累加器里加
var item = 1
var lai = function (n) {
for (var i = 1; i <= n; i++) {
item *= i / (2 * i + 1)
sum += item
}
return (sum + 1) * 2
}
console.log(lai(10000))
穷举法
寻找全部的水仙花数
- 遍历所有的 3 位数
- 把数字转换为字符串进行拆位,可以利用字符串的方法:charAt()方法
- 利用 if 进行条件匹配,输出结果
for (var i = 100; i < 1000; i++) {
var str = String(i)
var g = Number(str.charAt(2)) //个位
var s = Number(str.charAt(1))
var b = Number(str.charAt(0))
if (Math.pow(g, 3) + Math.pow(s, 3) + Math.pow(b, 3) === i) {
console.log(i) //153,370,371,407
}
}
循环嵌套
寻找 1-100 的所有质数
质数:只能够被 1 和它本身整除的数字,最小的质数是 2
outer: for (var i = 2; i <= 100; i++) {
// 内层循环开始从2开始到小于这个数字的每一个数字都尝试除i,如果能够整除,说明它不是质数,就可以筛选下一个数字了
for (var j = 2; j < i; j++) {
if (i % j == 0) {
// 说明数字i不是质数,因为它找到了除1和它自身之外的约数了,测试下一个数字了
// continue表示放弃这个数字,开始迭代下个数字,continue它负责的是它所在的最内层的for循环
// 要给外层for循环加上label,然后在continue的后面加上这个label,
// 这样就表示立即开始迭代外层for循环的下一个数字了,而不是内层for循环
continue outer
}
}
// 能够遇见这条语句的数字i,一定是质数,否则就被continue略过了
console.log(i)
}
鸡兔同笼
假设鸡有 a 只,兔有 b 只
for (var a = 0; a <= 35; a++) {
for (var b = 0; b <= 35; b++) {
if (a + b == 35 && 2 * a + 4 * b == 94) {
console.log('小鸡有' + a + '只,兔子有' + b + '只')
}
}
}