Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

类型转换规则 #23

Open
TieMuZhen opened this issue Nov 18, 2021 · 0 comments
Open

类型转换规则 #23

TieMuZhen opened this issue Nov 18, 2021 · 0 comments

Comments

@TieMuZhen
Copy link
Owner

TieMuZhen commented Nov 18, 2021

前言

正文

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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant