变量
常见错误类型
- 仅声明变量而没有赋值:undefined(无定义)
var a;
a // undefined
- 变量未声明就直接使用:not defined(没有声明)
x
// ReferenceError: x is not defined
变量提升法则
js引擎的工作方式:先解析代码,获取所有被声明的变量,然后再一行一行地运行。这造成的结果,就是所有的变量的声明语句,都会被提升到代码的头部,这就叫做变量提升(hoisting)。
console.log(a);
var a = 1;
这里a还没有声明和赋值,本应该是错误的,但是结果没有报错,而是显示undefined。
这是因为存在变量提升,将变量声明提到了前边,实际运行的是下边代码
var a;
console.log(a);
a = 1;
这里值得注意的是,提到前边的仅有变量声明,变量赋值不提到前边,所以结果是undefined
标识符(变量名+函数名)命名规则
- 第一个字符,可以是任意 Unicode 字母(包括英文字母和汉语等其他语言的字母),以及美元符号(
$
)和下划线(_
)。 - 第二个字符及后面的字符,除了 Unicode 字母、美元符号和下划线,还可以用数字
0-9
。 - 一些保留字不能用作标识符: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。
合法标识符
arg0
_tmp
$elem
π
临时变量
非法标识符
1a // 第一个字符不能是数字
23 // 同上
*** // 标识符不能包含星号
a+b // 标识符不能包含加号
-d // 标识符不能包含减号或连词线
条件语句
if...else语句
if
后面的表达式之中,不要混淆赋值表达式(=
)、严格相等运算符(===
)和相等运算符(==
)。尤其是赋值表达式不具有比较作用。
var x = 1;
var y = 2;
if (x = y) {
console.log(x);
}
// "2"
上边不小心将严格相等运算符写成赋值表达式,结果变成了将y
赋值给变量x
,再判断变量x
的值(等于2)的布尔值(结果为true
)。这种错误可以正常生成一个布尔值,因而不会报错。
为了避免这种情况,有些开发者习惯将常量写在运算符的左边,这样的话,一旦不小心将相等运算符写成赋值运算符,就会报错,因为常量不能被赋值。
if (x = 2) { // 不报错
if (2 = x) { // 报错
- 为什么优先采用“严格相等运算符”(
===
),而不是“相等运算符”(==
),请参考《运算符》章节。
switch语句
多个if...else
连在一起使用的时候,可以转为使用更方便的switch
结构。
- 需要注意的是,每个
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 (x) {
case 1:
console.log('x 等于1');
break;
case 2:
console.log('x 等于2');
break;
default:
console.log('x 等于其他值');
}
正确写法
- 需要注意的是,
switch
语句后面的表达式,与case
语句后面的表示式比较运行结果时,采用的是严格相等运算符(===
),而不是相等运算符(==
),这意味着比较时不会发生类型转换。
var x = 1;
switch (x) {
case true:
console.log('x 发生类型转换');
break;
default:
console.log('x 没有发生类型转换');
}
// x 没有发生类型转换
循环语句
do...while循环
循环至少运行一次,这是这种结构最大的特点
标签(label)
js语言允许语句的前面有标签(label),相当于定位符,用于跳转到程序的任意位置。通常与break
语句和continue
语句配合使用,跳出特定的循环
标签格式
label:
语句
foo: {
console.log(1);
break foo;
console.log('本行不会输出');
}
console.log(2);
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
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。