一、前言
在使用 js 的时候经常会出现要把非Number类型转为Number,而又因为 js 奇奇怪怪的转换规则而导致一头雾水。在这篇文章里我总结一下使用 + 和 ~~ 两种方式尝试把各类型转换为数字。
二、+ 的妙用
我曾做过一道题:
var a = false; var b = 1++a ;
问 b 为多少?
当时我看到这两个加号就隐约觉得不妙。。。实际上这里就用到了 “ + ”的类型转换规则
1++a 这个表达式执行顺序是这样的:1+(+a)即先用 “ + ” 把false转换为数字 0 ,然后再与 1 相加。
那么这里就有个问题了,既然false转为0,那其他类型会怎么样呢?我以各种类型做了实验,得出结果为:
String
(数字内容字符串)+“123” = 123 (非数字字符串)+“asd” = NaN (空字符串)+“” = 0
Boolean
(true)+true = 1 (false) +false = 0
null
+null = 0
undefined
+undefined = NaN
Symbol
+Symbol() = 错误:Cannot convert a Symbol value to a number 不能把Symbol类型转换为数字
Object
+{ } = NaN
Array
(空数组)+[ ] = 0 (一个数字的数组)+[1] = 1 (多个数字的数组)+[1,2] = NaN
Funciton
+ function f(){ } = NaN
NaN
+NaN = NaN
由上面的结果可以总结得出:只有 数字内容字符串(“123”)、空字符串(“”)、Boolean类型、null、空数组([ ])、单数字数组([1])可以转换为数字类型
由上面各种情形可知 + 如果遇到 undefined、Object等类型时就无能为力了,这样会导致运算结果不是数字。
我们的救星 ~ 位取反运算符就来了。
三、~~ 的妙用
~ 位取反运算符是把变量的底层数组取反。两次取反操作后会变成数字。
这里展示对各种类型测试的结果:
String
(数字内容字符串)~~“123” = 123 (非数字字符串)~~“asd” = 0 (空字符串)~~“” = 0
Boolean
(true)~~true = 1 (false) ~~false = 0
null
~~null = 0
undefined
~~undefined = 0
Symbol
~~Symbol() = 错误:Cannot convert a Symbol value to a number 不能把Symbol类型转换为数字
Object
~~{ } = 0
Array
(空数组)~~[ ] = 0 (一个数字的数组)~~[1] = 1 (多个数字的数组)~~[1,2] = 0
Funciton
~~ function f(){ } = 0
NaN
~~NaN = 0
由上述结果可得出结论:使用~~后除了Symbol不能转为数字,其他各类型都会转为数字,即使是 undefined 也不会出现NaN的情况。这可比 + 好用多了。