目录
一、语句与表达式
语句是为了完成某种任务而进行的操作,以分号结束,可以理解为一个行为。
表达式是为了得到返回值的计算式,可以放在任何需要一个值的地方,末尾不需要分号。
JavaScript的执行单位为行,即一行一行的执行下去。一般情况,一行就是一个语句,也可以一行放多个语句,但是为了可读性与降低维护成本,不建议这么做。
var a = 1 + 3; // 完整的语句,其中 1 + 3 为表达式
var a = 1 + 3 ; var b = 'abc'; // 一行可以放多个语句,不建议
分号前面可以没有任何内容,JavaScript 引擎将其视为空语句。
;;;
表达式后面添加分号,则 JavaScript 引擎就将表达式视为语句,只是单纯地产生一个值,并没有任何实际的意义。
1 + 3;
二、变量
变量是对“值”的具名引用,变量的名字即变量名,然后引用这个名字,就等同于引用这个值。
使用var变量声明命令,声明之后使用操作符 = 与表达式(字面量)建立引用关系:
var a = 1;
上面将变量的声明和赋值两个步骤合成了一行,是在实际开发中是经常用到的,但是要知道在JavaScript引擎中两个步骤实际上是分开的,等同于:
var a;
a = 1;
变量名的命名规则:
- 区分大小写,比如
A
和a
是两个不同的变量; - 可包含字母、数字、下划线 _ 和美元符号 $ ;
- 以字母开头,也可以 $ 和 _ 开头,但是不推荐,不能以数字开头;
- 不能使用JavaScript关键字和保留字,比如var、function、null等。
var a = 1;
var A = 1; // A 与 a 是两个不同的变量
var _underLine = 1, $dollarSign = 1; // 可以以下划线和美元符号开头,但是不建议
var 1a = 1; // 以数字开头报错
var function = 1; // 使用关键字或者保留字报错
未声明且从未出现的变量直接使用,会报错,而只声明暂未赋值的变量,默认值为undefined,表示无定义:
var a;
console.log(a); // undefined
声明变量并赋值的时候忘记使用var命令时是被允许的,但是会容易不知不觉地创建全局变量,污染全局环境,是很低级的写法:
var a = 1;
// 基本等同于:
a = 1;
JavaScript是一种动态类型的语言,所以变量的类型是没有限制的,可以随时更改类型:
var a = 1; // 此时a的类型为数值
a = 'string'; // 此时更改为字符串类型
在同一个作用域(深入学习会慢慢接触到作用域的概念)下,使用var声明一个已经存在的变量,是不会生效的,但是声明同名变量的同时进行赋值,会覆盖较早之前的变量:
var a = 1;
var a;
console.log(a); // 仍然输出 1,并不是undefined,说明不会覆盖
var b = 1;
var b = 2;
console.log(b); // 输出 2,说明赋值之后会覆盖
变量提升:因为JavaScript引擎的工作方式是先解析代码,获取全部被声明的变量,再逐行允许代码,所以导致了所有变量的声明语句都会被提升到代码的头部(与上面说到的变量的声明和赋值实际上会拆分为两个步骤相呼应)。
console.log(a); // 输出undefined,此时变量a暂未定义,但是因为变量提升不会报错
var a = 1;
实际上等同于:
var a;
console.log(a); // undefined,a 暂未赋值
a = a;
三、标识符
标识符指的是用来识别各种值的合法名称。最常见的标识符就是变量名,以及函数名。
JavaScript标识符的命名规则如下:
- 第一个字符必须以任意 Unicode 字母,下划线或者美元符号开头,不能是数字;
- 第二个字符及后面的字符,可以是任意 Unicode 字母,下划线,美元符号以及数字,不能是其他字符;
- 标识符区分字母大小写;
- 不能是关键字和保留字。
JavaScript 有一些保留字,不能用作标识符:arguments、break、case、catch、class、const、continue、debugger、default、delete、do、else、enum、eval、export、extends、false、finally、for、function、if、implements、import、in、instanceof、interface、let、new、null、package、private、protected、public、return、static、super、switch、this、throw、true、try、typeof、var、void、while、with、yield。
因为中文可以转换成Unicode编码,所以可以使用中文作为标识符,但是不建议:
var 临时变量 = 1;
四、注释
源码中被 JavaScript 引擎忽略的部分就叫做注释,它的作用是对代码进行解释。
单行注释:
// 单行注释
多行注释:
/*
多行注释
*/
由于历史上 JavaScript 可以兼容 HTML 代码的注释,所以<!--
和-->
也被视为合法的单行注释(日常开发不推荐使用):
<!-- 单行注释
--> 单行注释
五、区块
使用大括号将多个语句组合在一起,称为"区块"结构:
{
var a = 1;
console.log(1);
}
在ES6之前,上面的这种单独的区块对var命令声明的变量是没有单独作用域限制的。
单独的区块在实际开发中并不常见,更多的是用来构成复杂的语法结构,比如for
、if
、while
、function
等,其中function区块对var有单独作用域限制,即局部环境。
六、条件语句
if结构:
if (布尔值) 语句;
括号中的布尔值,是由条件表达式所产生的,所以可以放置任何一个可以转换成布尔值的表达式,if结构会对该表达式进行自动转换。
上述结构只能判断执行一个语句,想要执行多个语句需要使用大括号进行配合,实际上,即使只有一个语句也建议添加大括号包裹:
if (布尔值) {
语句1;
语句2;
}
if...else结构:
if结构的延伸,在if后面添加else区块,判断其他情况:
if (布尔值) {
语句...
} else {
语句...
}
对一个关联性很强的条件表达式多种情况进行判断时,采用多个if...else
语句连写的结构:
if (m === 0) {
// ...
} else if (m === 1) {
// ...
} else if (m === 2) {
// ...
} else {
// ...
}
switch结构:
上面的多个if...else语句连写的结构,其实可以转换成switch结构,使用起来更方便:
switch (m) {
case 0:
// ...
break;
case 1:
// ...
break;
case 2:
// ...
break;
default:
// ...
}
上面的结构中,根据m变量的值匹配相应的case值,匹配成功执行对应的语句,所有的case都不匹配则执行default选项的语句;
注意:case对应的break语句不能缺失,否则会导致继续执行接下来的case。变量m的值与每个case的值匹配机制采用的是严格相等模式(即 === 运算符),意味着比较时不会发生类型转换
三元运算符结构:
(条件表达式) ? 表达式1 : 表达式2
运算规则:条件表达式返回值为true则返回表达式1,返回值为false,则返回表达式2。
七、循环语句
while循环:
while (条件表达式) {
语句;
...
}
该循环语句,有可能条件表达式一开始就不为true导致一次都不执行。一般情况下,在循环体内需要存在条件表达式变动因素,使得循环能够结束,除非你需要的是无限循环:
var i = 1;
while (i < 100) {
console.log(i);
i = i + 1; // 表达式变动因素
}
// 以下循环为无限循环,因为循环体内没有变动因素,条件表达式一直都为true
while (i < 100) {
console.log(i);
}
for循环:
最常用的循环结构:
for (初始化表达式; 条件表达式; 递增递减表达式) {
语句集
}
for
语句后面的括号里面,有三个表达式。
- 初始化表达式(initialize):确定循环变量的初始值,只在循环开始时执行一次。
- 条件表达式(test):每轮循环开始时,都要执行这个条件表达式,只有值为真,才继续进行循环。
- 递增表达式(increment):每轮循环的最后一个操作,通常用来递增递减循环变量。
例子:
for (var i = 0; i < 100; i++) {
console.log(i);
}
do...while循环:
do...while
循环与while
循环类似,唯一的区别就是先运行一次循环体,然后判断循环条件。
do {
语句集
} while (条件表达式);
特点是,至少会允许一次循环体。
break语句和continue语句:
break
语句和continue
语句都具有跳转作用,可以让代码不按既有的顺序执行。
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);
}
}
over!