1. 关于整数和浮点数,在JavaScript中,所有数字都是以64位浮点数形式储存,即使是整数也是如此。也就是是说,1与1.0是严格相等的。
1 === 1.0 // true
这就是说,JavaScript 语言的底层根本没有整数,所有数字都是小数(64位浮点数)。容易造成混淆的是,某些运算只有整数才能完成,此时 JavaScript 会自动把64位浮点数,转成32位整数,然后再进行运算。
由于浮点数不是精确的值,所以涉及小数的比较和运算要特别小心。
0.1 + 0.2 === 0.3
// false
0.3 / 0.1
// 2.9999999999999996
(0.3 - 0.2) === (0.2 - 0.1)
// false
2. NaN是 JavaScript 的特殊值,表示“非数字”(Not a Number),主要出现在将字符串解析成数字出错的场合。
5 - 'x' // NaN
上面代码运行时,会自动将字符串x
转为数值,但是由于x
不是数值,所以最后得到结果为NaN
,表示它是“非数字”(NaN
)。
另外,一些数学函数的运算结果会出现NaN
。
Math.acos(2) // NaN
Math.log(-1) // NaN
Math.sqrt(-1) // NaN
0 除以 0 也会得到 NaN:
0 / 0 // NaN
需要注意的是,NaN不是独立的数据类型,而是一个特殊数值,它的数据类型依然属于Number
,使用typeof
运算符可以看得很清楚。
typeof NaN // 'number'
Tips: 关于Math对象,用的比较多的是:
* 返回绝对值 Math.abs(x);
* 返回圆周率 Math.BI;
* 对数进行上舍入 Math.ceil(x);
* 对数进行下舍入 Math.floor(x);
* 把数四舍五入为最接近的整数 Math.round(x);
* 返回0-1之间的随机数 Math.random();
* 返回x的y次幂 Math.pow(x,y);
* 返回x和y中的最高值 Math.max(x,y);
* 返回x和y中的最低值 Math.min(x,y);
如果想了解更多可以访问W3school,也可以在控制台中输入 Math.valueOf() 查看Math对象的属性和方法。
3.关于NaN的运算规则
NaN不等于任何值,包括它本身。
NaN === NaN // false
数组的indexOf
方法内部使用的是严格相等运算符,所以该方法对NaN
不成立。
[NaN].indexOf(NaN) // -1
NaN
在布尔运算时被当作false
。
NaN
与任何数(包括它自己)的运算,得到的都是NaN
。
Boolean(NaN) // false
NaN + 32 // NaN
NaN - 32 // NaN
NaN * 32 // NaN
NaN / 32 // NaN
4. 关于parseInt(),该方法用于将字符串转化为整数,如果字符串前有空格会自动去除
parseInt('123') // 123
parseInt(' 81') // 81
需要注意的是,如果parseInt的参数不是字符串,则会先转为字符串再进行转换。
parseInt(1.23) // 1
// 等同于
parseInt('1.23') // 1
字符串转为整数的时候,是一个个字符依次转换,如果遇到不能转为数字的字符,就不再进行下去,返回已经转好的部分。
parseInt('8a') // 8
parseInt('12**') // 12
parseInt('12.34') // 12
parseInt('15e2') // 15
parseInt('15px') // 15 在JS中多用于此
上面的代码中,parseInt
的参数都是字符串,结果只返回字符串头部可以转为数字的部分。
如果字符串的第一个字符不能转化为数字(后面跟着数字的正负号除外),返回NaN。
parseInt('abc') // NaN
parseInt('.3') // NaN
parseInt('') // NaN
parseInt('+') // NaN
parseInt('+1') // 1
所以,parseInt的返回值要么是一个十进制数,要么就是NaN。
Tips: parseInt还可以接受第二个参数,在2-36之间,表示被解析的进制,返回该值对应的十进制数。默认为10,即十进制转十进制。
parseInt('1000') // 1000
// 等同于
parseInt('1000', 10) // 1000
parseInt('1000', 2) // 8
parseInt('1000', 6) // 216
parseInt('1000', 8) // 512
如果第二个参数不在2-36这个范围,会返回NaN。如果为0,Null,undefined,则该参数会被忽略。
5. parseFloat() 用于将一个字符串转化为浮点数。如果转换的值包含不能转换为浮点数的字符,则会停止转换,返回已转换好的值。该方法也会自动忽略字符串前面的空格。
parseFloat('3.14') // 3.14
parseFloat('314e-2') // 3.14
parseFloat('0.0314E+2') // 3.14
parseFloat('3.14more non-digit characters') // 3.14
parseFloat('\t\v\r12.34\n ') // 12.34
如果参数不是字符串或者字符串的第一个字符不能转换为浮点数,则返回NaN。
parseFloat([]) // NaN
parseFloat('FF2') // NaN
parseFloat('') // NaN
上面的代码需要注意的是,parseFloat和parseInt会将空字符串转化为NaN。这点和Number函数不同。
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
6. isNaN()用来判断一个值是否是NaN。需要注意的是它的参数只能是数字,如果不是会先自动转换为数字。特殊的是如果是参数是一个字符串,字符串会自动先被转为NaN,返回的是true。数组和对象也类似字符串。所以,奇不奇怪?
isNaN(NaN) // true
isNaN(123) // false
isNaN('Hello') // true
// 相当于
isNaN(Number('Hello')) // true
isNaN({}) // true
// 等同于
isNaN(Number({})) // true
isNaN(['xzy']) // true
// 等同于
isNaN(Number(['xzy'])) // true
有所例外的是,对于空数组和只有一个数值成员的数组,isNaN()返回false。原因是在JavaScript的数据类型转换中,这些数组能被Number函数转化为数字。
Number([]) // 0
Number([123]) // 123
Number(['123']) // 123
isNaN([]) // false
isNaN([123]) // false
isNaN(['123']) // false
所以,重点来了,使用isNaN之前,最好判断一下数据类型。
function myIsNaN(value) {
return typeof value === 'number' && isNaN(value);
}
更好的方法是,利用NaN是唯一不等于自身的值这个特点:
function myIsNaN(value) {
return value !== value;
}
7.isFinite() 返回一个布尔值,表示某个值是否为正常的数值。
isFinite(Infinity) // false
isFinite(-Infinity) // false
isFinite(NaN) // false
isFinite(undefined) // false
isFinite(null) // true
isFinite(-1) // true
参数也会先进一步转化为数字所以除了Infinity,-Infinity,NaN,undefined这几个值会返回false,其他都会返回true。