可以在同一条var命令中声明多个变量。
var a, b;
a // undefined
b // undefined
如果使用var重新声明一个已经存在的变量,是无效的。
var x = 1;
var x;
x // 1
上面代码中,变量x声明了两次,第二次声明是无效的。
但是,如果第二次声明的时候还进行了赋值,则会覆盖掉前面的值。
var x = 1;
var x = 2;
// 等同于
var x = 1;
var x;
x = 2;
标识符
var π = 3.14
π // 3.14
var 临时变量 = 1
临时变量 // 1
注释
--> 这是一条合法的JS注释
<!-- 这是一条合法的JS注释
<!-- 这是一条合法的JS注释 -->
-->只有在行首,才会被当成单行注释,否则会当作正常的运算。
function countdown(n) {
while (n --> 0) console.log(n)
}
countdown(3) // 2 1 0
上面代码中,n --> 0实际上会当作n-- > 0,因此输出2、1、0。
条件语句
if结构
if (布尔值)
语句;
if (布尔值) 语句;
if (布尔值) {
语句;
...
}
let x = 2
if (x = 3) console.log(x)
// 3
if (2 = x) console.log(x)
// Uncaught ReferenceError: Invalid left-hand side in assignment
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语句,相当于下面这样。
if (m !== 1) {
if (n === 2) {
console.log('hello');
} else {
console.log('world');
}
}
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
语句部分,都可以使用表达式。
switch(1 + 3) { // 1 + 3
case 2 + 2: // 2 + 2
f();
break;
default:
neverHappens();
}
需要注意的是,switch语句后面的表达式,与case语句后面的表示式比较运行结果时,采用的是严格相等运算符(===),而不是相等运算符(==),这意味着比较时不会发生类型转换。
循环语句
while 循环
while (条件)
语句;
while (条件) 语句;
while (条件) {
语句;
}
for 循环
for (初始化表达式; 条件; 递增表达式)
语句
for (initialize; test; increment) {
语句
}
for语句的三个部分(initialize、test、increment),可以省略任何一个,也可以全部省略。
for ( ; ; ){
console.log('Hello World');
}
上面代码省略了for语句表达式的三个部分,结果就导致了一个无限循环。
do…while 循环
do...while循环与while循环类似,唯一的区别就是先运行一次循环体,然后判断循环条件。
do
语句
while (条件);
do {
语句
} while (条件);
不管条件是否为真,do...while循环至少运行一次,这是这种结构最大的特点。另外,while语句后面的分号注意不要省略。
let w = 5
do {
w--
console.log(w) // 4 3 2 1 0 -1
} while(w >= 0);
// 省略分号的测试结果
let v = 10
do {
v--
console.log(v) // 9 8 7 6 5 4
} while(v >= 5)
break 语句
var i = 0
while(i < 100) {
console.log('i 当前为:' + i)
// 上面代码只会执行10次循环,一旦i等于10,就会跳出循环。
i++
if (i === 10) break
}
for (var i = 0; i < 5; i++) {
console.log(i)
// 上面代码执行到i等于3,就会跳出循环
if (i === 3)
break
}
continue 语句
for (let i = 0; i <= 5; i++) {
if (i % 2) {
continue
// 如果i为奇数,直接进入下一轮循环
}
console.log(i) // 0 2 4
}
标签(label)
label:
语句
标签通常与break语句和continue语句配合使用,跳出特定的循环。
Use label
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
Without label
for (var i = 0; i < 3; i++) {
for (var j = 0; j < 3; j++) {
console.log('i=' + i + ', j=' + j);
}
}
// i=0, j=0
// i=0, j=1
// ... ...
// i=2, j=2
typeof 运算符
typeof function () {} // "function"
typeof undefined // undefined
typeof [] // "object"
typeof null // "object"
null 和 undefined
Number(null) // 0
Number(undefined) // NaN
布尔值
if ('') console.log('true') // 无输出
整数和浮点数
/**
* true
* JS内部,所有数字都以64位浮点数形式储存
* JavaScript 语言的底层根本没有整数
*/
1 === 1.0
由于浮点数不是精确的值,所以涉及小数的比较和运算要特别小心。
0.1 + 0.2 === 0.3 // false
0.3 / 0.1 // 2.9999999999999996
(0.3 - 0.2) === (0.2 - 0.1) // false
/**
* 精度最多只能到53个二进制位,
* 这意味着,
* 绝对值小于等于2的53次方的整数,
* 即-2的53次方到2的53次方,都可以精确表示。
*/
Math.pow(2, 53) // 9007199254740992
/**
* 出错
* 9007199254740992
*/
Math.pow(2, 53) + 1
// 多出的三个有效数字,将无法保存
9007199254740992111
// 9007199254740992000
数值范围
JS能够表示的数值范围为2的1024次方到2的-1023次方(开区间),超出这个范围的数无法表示。
Math.pow(2, 1024) // Infinity 正向溢出
Math.pow(2, -1075) // 0 负向溢出
Number.MAX_VALUE // 1.7976931348623157e+308
Number.MIN_VALUE // 5e-324
数值的表示法
.1e-23 // 1e-24
/**
* 小数点前的数字多于21位
* 1.2345678901234568e+21
*/
1234567890123456789012
/**
* 小数点后的零多于5个
* 3e-7
*/
0.0000003
0.000003 // 0.000003
数值的进制
0xff // 255 16进制
0o377 // 255 8进制
0b11 // 3 2进制
如果八进制、十六进制、二进制的数值里面,出现不属于该进制的数字,就会报错。
/**
* Uncaught SyntaxError:
* Invalid or unexpected token
*/
0xzz // 16进制出现 z
0o88 // 8进制出现 8
0b22 // 2进制出现 2
/**
* 通常来说,有前导0的数值会被视为八进制,
* 但是如果前导0后面有数字8和9,
* 则该数值被视为十进制。
*
* 前导0表示八进制,处理时很容易造成混乱。
* ES5 严格模式和 ES6中,已废除这种表示法。
*/
0888 // 888
0777 // 511
特殊数值
正零和负零
-0 === +0 // true
0 === -0 // true
0 === +0 // true
+0 // 0
-0 // 0
(-0).toString() // '0'
(+0).toString() // '0'
(1 / +0) === (1 / -0) // false
NaN
5 - 'x'
// NaN
Math.acos(2) // NaN
Math.log(-1) // NaN
Math.sqrt(-1) // NaN
0 / 0 // NaN
typeof NaN // 'number'
NaN === NaN // false
[NaN].indexOf(NaN) // -1
Boolean(NaN) // false
NaN + 32 // NaN
NaN - 32 // NaN
NaN * 32 // NaN
NaN / 32 // NaN
Infinity
Math.pow(2, 1024) // Infinity
0 / 0 // NaN
1 / 0 // Infinity
Infinity === -Infinity // false
1 / -0 // -Infinity
-1 / -0 // Infinity
Infinity大于一切数值(除了NaN),-Infinity小于一切数值(除了NaN)。
Infinity > 1000 // true
-Infinity < -1000 // true
Infinity与NaN比较,总是返回false。
Infinity > NaN // false
-Infinity > NaN // false
Infinity < NaN // false
-Infinity < NaN // false
parseInt()
parseInt(' 81') // 81
如果parseInt的参数不是字符串,则会先转为字符串再转换。
parseInt(1.23) // 1
// 等同于
parseInt('1.23') // 1
parseInt('abc') // NaN
parseInt('.3') // NaN
parseInt('') // NaN
parseInt('+') // NaN
parseInt('+1') // 1
parseInt('0x10') // 16
parseInt('011') // 11
/**
* 对于那些会自动转为科学计数法的数字,
* parseInt会将科学计数法的表示方法视为字符串,
* 因此导致一些奇怪的结果。
*/
parseInt(1000000000000000000000.5) // 1
// 等同于
parseInt('1e+21') // 1
parseInt(0.0000008) // 8
// 等同于
parseInt('8e-7') // 8
parseInt('1000', 2) // 8
parseInt('1000', 6) // 216
parseInt('1000', 8) // 512
parseInt('10', 37) // NaN
parseInt('10', 1) // NaN
parseInt('10', 0) // 10
parseInt('10', null) // 10
parseInt('10', undefined) // 10
parseInt('1546', 2) // 1
parseInt('546', 2) // NaN
parseFloat()
parseFloat(true) // NaN
Number(true) // 1
parseFloat(null) // NaN
Number(null) // 0
parseFloat('') // NaN
Number('') // 0
parseFloat('123.45#') // 123.45
Number('123.45#') // NaN
参考资料:
JavaScript标准参考教程(alpha)
网友评论