虽然有不少坑但是比较可靠的parseInt
Number.parseInt(string,radix) 默认接收两个参数
第一个参数是默认是 string 类型值,如果不是,会通过抽象的 ToString 强制转化成 string 类型的值。这其中就会有强制类型转换过程中的各种坑
第二个参数是 number 类型的进制,如果不是,会通过抽象的 ToNumber 强制转化成 number 类型的值,范围是 2-36,通过强制类型转换后如果是其他值会返回 NaN。在 ES5 之前如果没有传入这个参数,会根据第一个参数的开头来判断进制,0 开头的字符串会判断成八进制,也就是很多人提到的老黄历坑。ES5 之后已经解决,不传这个参数默认十进制。但是这个参数容易被忽略,尤其是在和 map 之类的也容易忽略后续可选参数的函数搭配使用的时候,比如
1 | ["1", "2", "3"].map(parseInt) // 结果是 [1, NaN, NaN] |
这里第一个结果是[1, NaN, NaN]的原因为:
map方法在调用callback函数时,会给它传递三个参数:当前正在遍历的元素, 元素索引, 原数组本身.
第三个参数parseInt会忽视, 但第二个参数不会,也就是说,parseInt把传过来的索引值当成进制数来使用.从而返回了NaN。
即实际是下面这样:
1 | parseInt("1", 0); // 这是特例, 按照 0 进制转成数, 直接得本身 |
所以如果只是用 parseInt 来 “取整”,一个良好的习惯是永远记得设置第二个参数为 10
最后提一点,在ES6中将全局对象的parseInt()和parseFloat()移植到了Number对象上面,行为完全不变。但Number.isFinite()和Number.isNaN()则是在内层借用了全局的相应方法,所以只能说ES6在Number对象上提供了isFinite()和isNaN()方法。
1 | alert(isFinite===Number.isFinite); //false |
巧妙使用位操作符
JavaScript 中的 number 类型的值都是使用 IEEE 754 标准的 64 位双精度浮点型存储,即 1 位符号位 + 11 位指数部分 + 52 位尾数部分 。用来表示整数时,安全的范围是 53 位,超出这个返回可能会造成精度丢失
- 按位或| 向下取整(数值不够大才能用)
1 | var num=-9999999.1234; |
关于其它的取整方法可以见博客中:“JS中的取整”
- 按位非~(按位取反)任意数值x相当于-(x+1)
1 | console.log(~1); //-2 |
我们可以发现:-1 是唯一一个经过 ~ 运算返回假值0的值(包括其他那些特殊的值比如 NaN、{}、[] 等都不会返回假值)
所以字符串和数组的 indexOf 函数查找失败会返回 -1,这时候就可以用:
1 | if(~str.indexOf('str')) // 来表示查找失败 |
比判断 >= 0 或者 != -1 更优雅,跟用 !! 来判断非假值有异曲同工之妙
- 按位与&取最后一位数字
eg:取任意数字的任意二进制位上的值(不是1就是0)
eg:128的第一到第7位是0,第八位是1(128=10000000)1
2
3
4
5
6
7
8
9
10/*
主要方法是和1按位与,
如10000
&
00001,这样就能取到10000的最后一位数字
*/
function valueAtBit(num,bit){
return (num>>(bit-1)) & 1;
}
console.log(valueAtBit(128,8)); //1
其它的骚操作
JS取0~9的一个随机数可以用:1
(Math.random()+"").slice(-1); //eg从0.984652315464中复制最后一个数字4