JS数据类型转换

真实项目中经常需要将数据类型之间进行转换.

1. 其他数据类型转换为number类型

1.1 发生情况

  • isNaN 检测的时候: 当被检测值不是数字类型, 浏览器会自己调用Number方法先将其转化为数字, 然后再检测是否为有效数字.
isNaN('3')     // false
// Number('3') -> 3 -> isNaN(3) -> false
isNaN('3px)     // true
// Number('3px') -> NaN -> isNaN(NaN) -> true
  • 基于 parseInt/parseFloat/Number 手动转换为数字类型
  • 进行数学运算 : + – * / % . 但要注意+不仅仅是数学运算, 还可能是字符串拼接
'3' - 1        // 2
// Number('3') -> 3 -> 3-1 -> 2
'3px' - 1       // NaN
'3px' + 1       // '3px1'

// 要注意 ++ 运算
var i = '3';
i = i + 1;      // '31'
i++;            // 4
  • 基于 == 比较的时候, 也会把其他值转化为数字类型

1.2 转换规律

浏览器自行转换都是基于Number方法进行的转换
– 把字符串转化为数字
– 只要遇到一个非有效数字字符结果就是NaN
– 空null、空字符串、空格、换行符、制表符转化为数字结果是0
– 把布尔类型转化为数字
– true -> 1
– false -> 0
– 把引用类型转化为数字
– 首先会调用toString方法转化为字符串, 然后再调用Number方法转化为数字

2. 其他数据类型转换为字符串类型

2.1 发生情况

  • 基于alert/confirm/prompt/doucment.write等方法输出内容的时候, 会把输出的值转化为字符串
alert(1)        // '1'
  • 基于+进行字符串拼接的时候
  • 把引用类型值转化为数字的时候, 首先会转化为字符串, 再将字符串转化为数字
  • 给对象设置属性名, 如果不是字符串, 首先会转化为字符串, 然后再当做属性名存储到对象中(对象的属性名只能是数字或字符串)
  • 手动调用toString/toFixed/join/String等方法的时候, 也是为了转化为字符串
var n = Math.PI;
n.toFixed(2)        // '3.14'
var ary = [12, 23, 34]
ary.join('+')       // '12+23+34'

2.2 转换规律

浏览器自行转换都是基于toString方法进行的转换
– 除了对象, 其他都是直接转化成字符串

1               // '1'
NaN             // 'NaN'
null            // 'null'
undefined       // 'undefined'

// 需要注意空数组的转换
[]              // '' , 转化为空字符串
[1]             // '1'
[1, 2]          // '1,2'

function(){}    // 'function(){}'
new Date()      //

// 对象: 无论是什么样的普通对象, 结果都是一样
{}              // '[object Object]'
{name:'xiaomi'} // '[object Object]'

3. 其他数据类型转换为布尔类型

3.1 发生情况

  • 基于!/!!/Boolean等方法进行的转换
  • 条件判断中的条件最终都是转化为布尔类型
// 把n转化为布尔类型验证条件真假, 真就执行
if (n){}

// 先计算表达式结果再转化为布尔类型进行判断
if('3px'+3){}

3.2 转换规律

  • 只有0/NaN/""/null/undefined这五个值转化为布尔类型是flase, 其余都是true

4. 特殊情况: 数学运送和字符串拼接

// 数学运算
1+true          // 2
// 字符串拼接
'1'+true        // '1true'

[12]+10         // '1210'   虽然没有字符串, 但是引用类型转化为数字首先会转化为字符串
[]+10           // '10'
({})+10         // '[object Object]10'
{}+10           // 10       这里大括号是一个代码块, +10才是真正的计算

思考题:

12+true+false+null+undefined+[]+'小米'+null+undefined+[]+true

12+true => 13
13+false => 13
13+null => 13
13+undefined => NaN
NaN+[] => NaN+'' => 'NaN'
'NaN'+'小米' => 'NaN小米'
'NaN小米'+null => 'NaN小米null'
'NaN小米null'+undefined => 'NaN小米nullundefined'
'NaN小米nullundefined'+[] => 'NaN小米nullundefined'
'NaN小米nullundefined'+true => 'NaN小米nullundefinedtrue'

==在比较的时候, 如果两边数据类型不一致, 则会先转化成相同数据类型再进行比较

  • 对象==对象. 不一定相等. 因为对象操作的是引用地址, 地址不同, 则不相等.
{name:'ccc'}=={name:'ccc'} => false
[]==[] => false

var obj1 = {};
var obj2 = obj1;
obj1==obj2 => true

不同类型的比较都是转化成数字后再进行比较:
– 对象==数字. 把对象转化成数字后再比较
– 对象==布尔. 把对象和布尔都转化成数字后再比较
– 对象==字符串. 把对象和字符串转化成数字后再比较
– 字符串==数字. 字符串转化为数字
– 字符串==布尔. 都转化成数字
– 布尔==数字. 布尔转化成数字

null和undefined的比较:
– null==undefined => true
– null===undefined => false
– null&&undefined和其他值比较都不相等
– NaN==NaN => false NaN和谁都不相等包括自己

1==true     // true
1==false    // false
2==true     // false

[]==false   // true 都转化成数字 0==0
[]==true    // false
![]==false  // true 先算![], 把数组转化为布尔再取反结果为false false==false
![]==true   // false
![] => !(toBoolean([])) => !true => false // 只有`0/NaN/""/null/undefined`这五个值转化为布尔类型是flase, 其余都是true

原创文章,作者:tipak,如若转载,请注明出处:http://www.myqqu.com/note/javascript_lessons/js-shujuleixingzhuanhuan.html