一. 定义
隐式转换是指在 JavaScript 中,当运算符在运算时,如果两边数据不对立,CPU 就无奈计算,这时咱们编译器会主动将运算符两边的数据做一个数据类型转换,转成一样的数据类型再计算。这种无需程序员手动转换,而由编译器主动转换的形式就称为隐式转换。
二. 转换规则
JavaScript 的类型分为根本数据类型和援用数据类型:
根本数据类型:Undefined、Null、String、Number、Boolean、(Symbol)->ES6
援用类型:Object
其间接转换规则如下表:
而当应用运算符时,两边不同的数据类型的主动转换有一套本人的默认规定,在 JavaScript 权威指南中这么阐明:
以下面的解释,归类为以下规定:
转为 String 类型:+(字符串连接符 String(1) + "10" = "1" + "10" = "110"
转为 Number 类型:++ / -- (自增自减运算符) + - * / %(算术运算符) > < >= <= == != === !== (关系运算符)
转为 Boolean 类型:!(逻辑非运算符)
转为布尔类型成为 false 的有:undefined、null、空字符串、0、-0、NaN
new Number() 和 Number() 是不同的,new Number() 创立了一个 Number 对象,Number() 将传入的参数转换为数值字面量
再举一些例子:
1 + "true" // "1true" 若 + 两边存在一个字符串,将另一个也转为字符串进行字符串拼接 String(1) + "true" = "1true"
1 + true // 2 这里的 + 是算术运算符 1 + Number(true) = 1 + 1 = 2
1 + undefined // NaN 这里的 + 是算术运算符 1 + Number(undefined) = 1 + NaN = NaN
1 + null // 1 这里的 + 是算术运算符 1 + Number(null) = 1 + 0 = 1
1 + "10" // "110" 这里的 + 是字符串连接符 String(1) + "10" = "1" + "10" = "110"
1 - "10" // -9 这里的 + 是算术运算符 1 - Number("10") = 1 - 9 = -9
// 不要混同字符串连接符与算术运算符隐式转换规则
"2" > 10 // false Number(2) > 10 = 2 > 10 = false
"2" > "10" // true 当两边都是字符串的时候,此时转为 number 而后比拟关系,留神这里并不是依照 Number()的模式转为数字,而是依照字符串对应的 unicode 编码来转成数字,charCodeAt(index) index 为字符下标,默认为 0。"2".charCodeAt(0) > '10'.charCodeAt(0) = 50 > 49 = true
"abc" > "b" // false 多个字符的时候从左往右顺次比拟 'a'.charCodeAt(0) = 97 'b'.charCodeAt(0) = 98
"abc" > "aad" // true
NaN == NaN // false
非凡状况:如果数据类型是 undefined 或 null 得出固定后果
undefined == undefined // true
undefined == null // true
null == null // true
NaN == NaN // false
三、对象的类型转换
// 对象转为布尔值始终为 true
// 对象
var a = {b: 1}
a.toString() ⇒ "[object Object]"
a.valueOf() ⇒ {b: 1}
// 数组
var a = [1,2,3]
a.toString() ⇒ "1,2,3"
a.valueOf() ⇒ [1, 2, 3]
// 函数
var a = function () { b =333; return 111;}
a.toString() ⇒ "function(){b =333; return 111;}"
a.valueOf() ⇒ ƒ () {b =333; return 111;}
// 日期
var a = new Date()
a.toString() ⇒ "Thu Mar 07 2019 13:48:31 GMT+0800 (中国规范工夫)"
a.valueOf() ⇒ 1551937711874
// 谬误
Error
toString()返回:"Error {谬误形容}"
valueOf()返回:谬误自身
// 正则表达式
var a = new RegExp('^ass[^f]\w?','gi')
a.toString() ⇒ "/^ass[^f]\w?/gi"
a.valueOf() ⇒ "/^ass[^f]\w?/gi"
四、总结和实际
1、算术运算符(+、-、*、/、++、–、%…)
'+'
作为一个双目运算符:若 + 两边存在一个字符串
,将另一个也转为字符串进行字符串拼接。
其余状况下,不论双目还是单目,都转为 数值类型
2、关系运算符(>、<、==、!=…)
===
、!==
:同时对比类型和值,两个都为真才返回真 ==
、!=
: 若两边均为对象,比照它们的援用是否雷同!(逻辑非)
: 将其后变量或表达式转为布尔值 比照字符串
:从头至尾扫描一一比拟每个字符的unicode
码,直到分出大小 其余状况下,两边均转为数值类型
NaN 与任何值都不雷同,与任何值比拟都返回 false
对象类型在运算时进行类型转换都先调用 valueOf()办法,再尝试 toString()办法
在进行对象字面量 (这里说的是 JSON 格局的对象字面量) 运算时要留神,若运算符两边都是字面量,则将它们都视为对象字面量进行类型转换;若只有一个字面量时要留神,当这个字面量在首位时,会被当做一个块对待。
{} + {} => "[object Object][object Object]"
{}被当做一个块,相当于执行 ( {}, +[]),计算的是 +[]的后果
{} + [] => 0
{a: 1} + [] => 0
{} == [] => 报错 ({}, ==[]) => 报错
变量模式运算失常
var a = {q:1}
a + [] => "[object Object]"
[] + a => "[object Object]"
[1,2,3] + [] => "1,2,3" + ""=>"1,2,3"[] + {} =>"" + "[object Object]" => "[object Object]"
[] == 0 // true [] => "" => 0
![] == 0 // true ![] => false => 0
[] == ![] // true [] => "" => 0 ![] => false => 0
[] == [] // false 比拟援用地址
{} == {} // false 比拟援用地址
{} == !{} // false !{} => false => 0 {} => "[object Object]" => Number("[object Object]") => NaN