Skip to content

类型转换规则 #23

Open
Open
@TieMuZhen

Description

@TieMuZhen

前言

正文

toString方法不太了解的小伙伴可以查看下面MDN的解释:

  • 除了nullundefined之外,其他的类型(数值、布尔、字符串、对象)都有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。

隐式类型转换

隐式转换,规则如下:

  • -、*、/、% :一律转换成数值后计算
  • +:
  1. 数字 + 字符串 = 字符串, 运算顺序是从左到右
  2. 数字 + 对象, 对象按照对象转换规则转换成原始类型,再比较
  3. 数字 + boolean/null -> 数字
  4. 数字 + undefined -> NaN
  • [1].toString() === '1'
  • {}.toString() === '[object object]'
  • NaN !== NaN+undefinedNaN

对象如何转换成原始数据类型

如果部署了 [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

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions