表达式和语句
JavaScript 程序的执行单位为行(line),也就是一行一行地执行。一般情况下,每一行就是一个语句。
-
语句(statement) 是为了完成某种任务而进行的操作。
-
表达式(expression) 指一个为了得到返回值的计算式。
语句主要为了进行某种操作,一般情况下不需要返回值;
表达式则是为了得到返回值,一定会返回一个值。凡是 JavaScript 语言中预期为值的地方,都可以使用表达式。
var a = 1 ; // 这是一个语句
// 以下为表达式
1+3; //表达式的值为3
add(1,2); //表达式的值为函数的返回值
console.log; //表达式的值为函数本身
console.log(3); //表达式的值为undefined,打印出来的东西是3
常考点1:console.log(3)表达式的值为undefined
只有函数才有返回值,值是值,返回值是返回值。
console.log(3); //表达式的值为undefined,打印出来的东西是3。
常考点2:return后不可加回车
大部分空格和回车无实际意义,但是return后面不可以加回车。
因为return后面加回车会自动补充undefined。
标识符
标识符(identifier)指的是用来识别各种值的合法名称。最常见的标识符就是变量名,以及后面要提到的函数名。JavaScript 语言的标识符对大小写敏感,所以a和A是两个不同的标识符。
标识符命名规则如下。
- 第一个字符,可以是任意 Unicode 字母(包括英文字母和其他语言的字母),以及美元符号(
$)和下划线(_)。 - 第二个字符及后面的字符,除了 Unicode 字母、美元符号和下划线,还可以用数字
0-9。
下面这些则是不合法的标识符。
1a // 第一个字符不能是数字
23 // 同上
*** // 标识符不能包含星号
a+b // 标识符不能包含加号
-d // 标识符不能包含减号或连词线
中文是合法的标识符,可以用作变量名。
var 临时变量 = 1;
区块
JavaScript 使用大括号,将多个相关的语句组合在一起,称为“区块”(block)。
条件语句
if 结构
if (布尔值)
语句;
// 或者
if (布尔值) 语句;
if (m === 3) {
m += 1;
}
建议总是在if语句中使用大括号,因为这样方便插入语句。
注意,if后面的表达式之中,不要混淆赋值表达式(=)、严格相等运算符(===)和相等运算符(==)。尤其是赋值表达式不具有比较作用。
常考点3:if语句只会包括离他最近的那一句
var a=1;
if (a === 3)
console.log(a);
console.log("a=2");
//会打印出 a=2
var a=1;
if (a === 3)
console.log(a)
console.log("a=2")
//会打印出 a=2
两者效果一样
; 后面即是下一句语句,若是 , 则表示话没说完。
var a=1;
if (a === 3)
console.log(a),console.log("a=2")
//无东西打印
if...else 结构
if (m === 3) {
// 满足条件时,执行的语句
} else if{
// 不满足条件时,执行的语句
} else {
// 还是不满足条件时,执行的语句
}
else代码块总是与离自己最近的那个if语句配对。
var m = 1;
var n = 2;
if (m !== 1)
if (n === 2) console.log('hello');
else console.log('world');
上面代码不会有任何输出,else代码块不会得到执行,因为它跟着的是最近的那个if语句,相当于下面这样。
var m = 1;
var n = 2;
if (m !== 1) {
if (n === 2) {
console.log('hello');
} else {
console.log('world');
}
}
如果想让else代码块跟随最上面的那个if语句,就要改变大括号的位置。
if (m !== 1) {
if (n === 2) {
console.log('hello');
}
} else {
console.log('world');
}
// world
switch 结构
多个if...else连在一起使用的时候,可以转为使用更方便的switch结构。
switch (fruit) {
case "banana":
// ...
break;
case "apple":
// ...
break;
default:
// ...
}
每个case代码块内部的break语句不能少,否则会接下去执行下一个case代码块,而不是跳出switch结构。
var x = 1;
switch (x) {
case 1:
console.log('x 等于1');
case 2:
console.log('x 等于2');
default:
console.log('x 等于其他值');
}
// x等于1
// x等于2
// x等于其他值
需要注意的是,switch语句后面的表达式,与case语句后面的表示式比较运行结果时,采用的是严格相等运算符(===),而不是相等运算符(==),这意味着比较时不会发生类型转换。
var x = 1;
switch (x) {
case true:
console.log('x 发生类型转换');
break;
default:
console.log('x 没有发生类型转换');
}
// x 没有发生类型转换
上面代码中,由于变量x没有发生类型转换,所以不会执行case true的情况。
三元运算符 ? :
(条件) ? 表达式1 : 表达式2
如果“条件”为true,则返回“表达式1”的值,否则返回“表达式2”的值。
&&短路逻辑
(表达式) && 执行语句
*若表达式为真,则继续执行后面的语句,若为假,则不继续执行,直接返回表达式的值。
A && B && C && D 取第一个假值或者D
||短路逻辑
(表达式) || 执行语句
若表达式为真,则取表达式的值,若为假,则继续执行。
A && B && C && D 取第一个真值或者D
循环语句
while 循环
While语句包括一个循环条件和一段代码块,只要条件为真,就不断循环执行代码块。
while (条件)
语句;
// 或者
while (条件) 语句;
while语句的循环条件是一个表达式,必须放在圆括号中。代码块部分,如果只有一条语句,可以省略大括号,否则就必须加上大括号。
while (条件) {
语句;
}
常考点4:while语句无返回值,不成立会立刻退出
常考点5:以下代码会立刻无限循环,因为浮点数不精确
var a=0.1;
while (a!==1) {
console.log(a);
a=a+0.1;
}
for 循环
for (初始化表达式; 条件; 递增表达式) {
语句
}
执行顺序:
- 先执行初始表达式
- 判断条件是否满足
- 若为真,执行循环体,再立刻执行递增表达式
- 不成立则退出
for (var i = 0; i < 3; i++) {
console.log(i);
}
// 0
// 1
// 2
常考点6:再立刻执行递增表达式。此时,i为3
常考点7:
for (var i = 0; i < 3; i++) {
setTimeout(()=>{console.log(i)},0)
}
//打印3个3
for (var i = 0; i < 3; i++) {
}
setTimeout(()=>{console.log(i)},0)
//打印一个3
setTimeout表示过一会再执行里面的语句,但是for循环会执行完,执行完for循环之时i=3,故而,会打印3出来。
do...while 循环
do...while循环与while循环类似,唯一的区别就是先运行一次循环体,然后判断循环条件。
do
语句
while (条件);
// 或者
do {
语句
} while (条件);
不管条件是否为真,do...while循环至少运行一次,这是这种结构最大的特点。另外,while语句后面的分号注意不要省略。
下面是一个例子。
var x = 3;
var i = 0;
do {
console.log(i);
i++;
} while(i < x);
break 语句和 continue 语句
break语句和continue语句都具有跳转作用,可以让代码不按既有的顺序执行。
break语句用于跳出代码块或循环。
var i = 0;
while(i < 100) {
console.log('i 当前为:' + i);
i++;
if (i === 10) break;
}
上面代码只会执行10次循环,一旦i等于10,就会跳出循环。
for循环也可以使用break语句跳出循环。
for (var i = 0; i < 5; i++) {
console.log(i);
if (i === 3)
break;
}
// 0
// 1
// 2
// 3
上面代码执行到i等于3,就会跳出循环。
continue语句用于立即终止本轮循环,返回循环结构的头部,开始下一轮循环。
var i = 0;
while (i < 100){
i++;
if (i % 2 === 0) continue;
console.log('i 当前为:' + i);
}
上面代码只有在i为奇数时,才会输出i的值。如果i为偶数,则直接进入下一轮循环。
如果存在多重循环,不带参数的break语句和continue语句都只针对最内层循环。
标签(label)
JavaScript 语言允许,语句的前面有标签(label),相当于定位符,用于跳转到程序的任意位置,标签的格式如下。
label:
语句
标签可以是任意的标识符,但不能是保留字,语句部分可以是任意语句。
标签通常与break语句和continue语句配合使用,跳出特定的循环。
top:
for (var i = 0; i < 3; i++){
for (var j = 0; j < 3; j++){
if (i === 1 && j === 1) break top;
console.log('i=' + i + ', j=' + j);
}
}
// i=0, j=0
// i=0, j=1
// i=0, j=2
// i=1, j=0
上面代码为一个双重循环区块,break命令后面加上了top标签(注意,top不用加引号),满足条件时,直接跳出双层循环。如果break语句后面不使用标签,则只能跳出内层循环,进入下一次的外层循环。
标签也可以用于跳出代码块。
foo: {
console.log(1);
break foo;
console.log('本行不会输出');
}
console.log(2);
// 1
// 2
上面代码执行到break foo,就会跳出区块。
continue语句也可以与标签配合使用。
top:
for (var i = 0; i < 3; i++){
for (var j = 0; j < 3; j++){
if (i === 1 && j === 1) continue top;
console.log('i=' + i + ', j=' + j);
}
}
// i=0, j=0
// i=0, j=1
// i=0, j=2
// i=1, j=0
// i=2, j=0
// i=2, j=1
// i=2, j=2
上面代码中,continue命令后面有一个标签名,满足条件时,会跳过当前循环,直接进入下一轮外层循环。如果continue语句后面不使用标签,则只能进入下一轮的内层循环。