js中的类型转换

类型转换分为两种 强制类型转换和隐式类型转换

强制类型转换

强制类型转换主要指Number()、String()、 Boolean三个函数,手动将各种类型的值,分别转换为数字,字符串或者布尔值

Number()

主要分为两种,一种是参数是原始类型,一种是参数是对象

原值类型的值

//数值,转换后还是原来的值
Number(324) //324
//字符串:如果可以被解析位数值,则转换为相应的数值
Number('324') // 324
//字符串:如果不能解析为数值,返回NaN
Number('324abc')// NaN
//空字符串转换为0
Number('')//0

//布尔值: true为1 false为0
Number(true)//1
Number(false)//0

//undefined 转化为NaN
Number(undefined) // NaN

//null 转为0

Number(null) //0

Number 函数将字符串转为数值,要比parseInt函数严格很多,基本上,只要有一个字符串无法转为数值,整个字符串就会转为NaN

parseInt('42 cat')// 42

Number('42 cat') // NaN

另外。parseInt和Number函数都会自动过滤一个字符串前导和后缀的空格

parseInt('\t\v\r12.34\n') // 12
Number('\t\v\r12.34\n') // 12.34

对象

简单的规则是,Number 方法的参数是对象时,将返回NaN,除非是包含单个数值的数组

Number ({a:1}) // NaN
Number ([1,2,3]) // NaN
Number ([5]) // 5
Number (['1']) // 1
Number ([]) // 0

原因 

  • 调用对象自身的valueOf 方法,如果返回原始类型的值,则直接对该对象使用Number函数,不在进行后续步骤
  • 如果valueOf方法返回的还是对象,则改为调用对象自身的toString 方法,如果toString方法原始类型的值则该对象使用Number函数,不在进行后续步骤
  • 如果toString 方法返回的是对象,就报错
var obj = {a:1}
Number(obj) // NaN

等同于

if (typeof obj.valueOf() === 'object') {
Number(obj.toString());
} else {
Number(obj.valueOf());
}

String()

String函数可以将任意类型的值转化为字符串,转换规则如下:

原始类型:

  • 数值: 转为为相应的字符串
  • 字符串: 不动
  • 布尔值: true转换为"true“ false转换为”false“
  • undefined: 转换为"undefined"
  • null: 转换为“null”
String(123) // "123"
String('abc') // "abc"
String(1e21) // '1e+21' 
String(true) // "true"
String(undefined) // "undefined"
String(null) // "null"

对象

string 方法的参数如果是对象,返回一个类型字符串,如果是数组,返回该数组的字符串形式,相当于调用数组的Array.prototype.join() 方法

String({a: 1}) // [object, object]

Strng ([]) // ''
string([1,2,4]) // "1,2,4"

//数组中的null或者undefined,会被当成成空字符串处理
String([1,undefined,3]) // "1,,3"

String 的转换规则与Number方法 基本相同,只是先调用toString方法,在调用valueOf方法

同样toString和valueOf可以自定义

String ({
toString: function () {
return 3;
}
})
// "3"
String ({
valueOf; function () {
return 2;
}
})
// "[object, object]"

String ({
valueOf: function () {
return 2;
},
toString: function () {
return 3;
}
})
// "3"

Boolean()

Boolean() 函数可以将任意类型的值转为布尔值

他的转化规则相对简单,除了以下五个值转化结果为false,其他的值全部为true

  • undefined
  • null
  • 0 (包含-0 和+0)
  • NaN
  • '' (空字符串)

所有对象(包括空对象)的转化结果都是true.甚至连false 对应的布尔对象new Boolean(false) 也是 true

隐式转换

隐式转换是以强制转换为基础的

遇到一下三种情况时,javascript会自动转换数据类型,

  • 第一种,不同类型的数据互相运算
// 其中最常见的就是数字与字符串的运算
//+运算符会将数字转换为字符串,而 - / * 则是将字符串转化为数字

123 + '123' // 123123
123-'123' // 0
'123'/123 // 1
  • 对非布尔值类型的数据求布尔值
if('abc') {
console.log('hello')
}除了以下几个值值其他的都是true
undefined null +0 -0 NaN ''(空字符串)
可以使用!运算法将其转换为true 
if (! undefined && !null && !0 && !NaN && ! ''){
console.log('hello')
}


//下面这种写法,有时也会讲一个表达式转为布尔值

expression ? true : false
  • 对非数值类型使用一元运算符
+ {foo : 'bar'} // NaN
- [1,2,3] // NaN
//在一元运算符中 + 是将与字符串相加转为字符串
'5' + 1 // '51'
'5' + true // "5true"
'5' + false // "5false"
'5' + {} // "5[object Object]"
'5' + [] // "5"
'5' + function (){} // "5function (){}"
'5' + undefined // "5undefined"
'5' + null // "5null"


'5' - '2' // 3
'5' * '2' // 10
true - 1  // 0
false - 1 // -1
'1' - 1   // 0
'5' * []    // 0
false / '5' // 0
'abc' - 1   // NaN
null + 1 // 1
undefined + 1 // NaN

js中的 == 与 ===

规则如下:

相等和不相等---先转换在比较 (==)

全等和不全等---仅比较不转换 (===)

== 是对值得比较而 === 不仅比较值还比较类型

==的比较过程

  • 如果有一个操作数是布尔值,则在比较相等性之前先将其转换为数值 --- false转换为0 true 转换为1
  • 如果一个操作数是字符串,另一个操作数是数值,在比较相等性之前想将字符串转换为数值
  • 如果一个操作数是对象,另一个操作数不是,则调用对象的valueOf()方法,用得到的基本类型按照前面的规则进行比较
  • 如果两个值的类型相同,在比较=== 是否相同
  • 如果两个值得类型不同,也有可能比较,会进行类型的隐式转换
  1. 如果一个是null ,一个是undefined 那么相等
  2. 如果一个是字符串,一个是数值,把字符串转换为数值之后在进行比较

=== 的比较过程

  • 如果类型不同,就一定不相等
  1. 如果两个都是数值,并且是同一个值,那么相等,如果是NaN则不相等
  2. 如果两个是字符串,每个位置都一样,那么相等,否则不相等
  3. 如果两个值都是true,或是false那么相等
  4. 如果两个值都是null 或者是undefined,那么相等
1 == 1 // true
1 === Number(1) // false
NaN == NaN // false

null == undefined // true
1 == '1' //true
1 === '1' // false
'9'< '10' // false 字符串的标胶按位比较, 数字字符比较的ASIC码,没有数字的asic只有0-9 48- 57
 大写字符的顺序是 65-90 小写字符的顺序是 97-122

typeof [] === 'array' // false typeof 只能判断基本类型,对象只能判断出 object typeof [] 的结果为 object

'null' == 'undefined' // false 这是字符串的比较
[] == ![] // true
{} == !{} // false

根据运算符优先级, !的优先级是大于== 的 所以会先执行![]

!运算符会将转换为boolean类型,其中 null, undefined, NaN,(' ')为false 其余都是true

所以 ![]的结果是false 

根据上面的规则(如果有一个操作数是布尔值,则在比较相等性之前先将其转换为数值) 那么 ![] = false = 0

那么比较变成了 [] == 0

再根据上面的规则 (如果一个操作数是对象另一个操作数不是,则调用该对象的valueOf()方法,获取其值,用得到的基本类型按照前面的规则比较,如果对象没有valueOf()方法,则调用toString() 方法)

而对于空数组,[].toString() -> ''  (返回的是空字符串)

则比较变成了 '' == 0

再根据上面的规则 (如果一个操作数是字符串,另一个操作数是数值,在比较相等性之前将字符串转换为数值)

Number ('') -> 0

则变成了 0 == 0   // true

总结如下:

[] == ![] -> [] == false  -> [] == 0  -> '' == 0 -> 0 == 0 -> true

那么对于 {} == !{} 也是同理

关键在于 {}.toString() -> NaN

{} ==!{} -> {} == false -> {} == 0 -> NaN == 0 -> false

上一篇:现代JavaScript 教程(JavaScript基础知识)总结


下一篇:JS 原生过滤掉 null、undefined、空串、NaN