Description
前言
正文
toString
方法不太了解的小伙伴可以查看下面MDN的解释:
- 除了
null
和undefined
之外,其他的类型(数值、布尔、字符串、对象)都有toString()
方法,它返回相应值的字符串表现(并不修改原变量)。 - 每个对象都有一个
toString()
方法。 - 当该对象被表示为一个文本值时,或者一个对象以预期的字符串方式引用时自动调用。
- 默认情况下,
toString()
方法被每个Object
对象继承。如果此方法在自定义对象中未被覆盖,toString()
返回"[object type]"
,其中type
是对象的类型。
Object.prototype.toString.call(1) // '[object Number]'
Object.prototype.toString.call(false) // '[object Boolean]'
Object.prototype.toString.call("") // '[object String]'
Object.prototype.toString.call({}) // '[object Object]'
Object.prototype.toString.call(function fn(){}) // '[object Function]'
对比typeof
typeof {} // 'object'
typeof (function fn(){}) // 'function'
typeof 1 // 'number'
typeof "" // 'string'
typeof false // 'boolean'
JS中类型转换分为强制类型转换
和隐式类型转换
。
-
通过 Number()、parseInt()、parseFloat()、toString()、String()、Boolean(),进行强制类型转换。
-
逻辑运算符(&&、 ||、 !)、运算符(+、-、*、/)、关系操作符(>、 <、 <= 、>=)、相等运算符(==)或者 if/while 的条件,可能会进行隐式类型转换。
强制类型转换
1.Number() 将任意类型的参数转换为数值类型
规则如下:
- 如果是布尔值,true和false分别被转换为1和0
- 如果是数字,返回自身
- 如果是 null,返回 0
- 如果是 undefined,返回 NAN
- 如果是字符串,遵循以下规则:
(1) 如果字符串中只包含数字(或者是 0X / 0x 开头的十六进制数字字符串,允许包含正负号),则将其转换为十进制
Number("12")
// 12
(2) 如果字符串中包含有效的浮点格式,将其转换为浮点数值
Number("12.12")
// 12.12
(3) 如果是空字符串""
或" "
,将其转换为0
Number(" ")
// 0
(4) 如不是以上格式的字符串,均返回 NaN
Number("a")
// NaN
- 如果是Symbol,抛出错误
- 如果是对象,则先调用对象的
valueOf()
方法,然后依据前面的规则转换返回的值。如果转换的结果是 NaN ,则再调用对象的toString()
方法,再次依照前面的规则转换返回的字符串值。
2.parseInt(param, radix)
-
如果第一个参数传入的是字符串类型:
1、忽略字符串前面的空格,直至找到第一个非空字符,如果是空字符串,返回NaN
2、如果第一个字符不是数字符号或者正负号,返回NaN
3、如果第一个字符是数字/正负号,则继续解析直至字符串解析完毕或者遇到一个非数字符号为止 -
如果第一个参数传入的Number类型:
数字如果是0开头,则将其当作八进制来解析(如果是一个八进制数);如果以0x开头,则将其当作十六进制来解析 -
如果第一个参数是 null 或者是 undefined,或者是一个对象类型:
返回 NaN -
如果第一个参数是数组:
去数组的第一个元素,按照上面的规则进行解析 -
如果第一个参数是Symbol类型:
抛出错误 -
如果指定radix参数,以radix为基数进行解析
parseInt(10101, 2) // 21
parseInt(0111); //八进制数 73
parseInt('');//NaN
parseInt('0X11'); //17
parseInt('1a') //1
parseInt('a1'); //NaN
parseInt(['10aa','aaa']);//10
parseInt([]);//NaN;
parseInt(undefined); // NaN
注: NaN是非常特殊的值,它不和任何类型的值相等,包括它自己,同时它与任何类型的值比较大小时都返回false。
隐式类型转换
隐式转换,规则如下:
- -、*、/、% :一律转换成数值后计算
- +:
- 数字 + 字符串 = 字符串, 运算顺序是从左到右
- 数字 + 对象,
对象
按照对象转换规则
转换成原始类型
,再比较 - 数字 +
boolean/null
-> 数字 - 数字 +
undefined
->NaN
[1].toString() === '1'
{}.toString() === '[object object]'
NaN !== NaN
、+undefined
为NaN
对象如何转换成原始数据类型
如果部署了 [Symbol.toPrimitive] 接口,那么调用此接口,若返回的不是基础数据类型
,抛出错误。
如果没有部署 [Symbol.toPrimitive] 接口,那么先返回 valueOf() 的值,若返回的不是基础类型
的值,再返回 toString() 的值,若返回的不是基础类型的值, 则抛出异常。
//先调用[Symbol.toPrimitive],然后调用 valueOf, 最后调用 toString
let obj = {
[Symbol.toPrimitive]() {
return 200;
},
valueOf() {
return 300;
},
toString() {
return 'Hello';
}
}
//如果 valueOf 返回的不是基本数据类型,则会调用 toString,
//如果 toString 返回的也不是基本数据类型,会抛出错误
console.log(obj + 200); //400