浅谈JS的数据类型转换

556 阅读5分钟

经过对js的数据类型转换的学习,总结一下相关的转换情况,以及一些类型判断的细节点,有什么不足的地方希望大家指正

数据类型转换主要分为以下四种:

一、把其他数据类型转换为 number 类型
  1. 特定需要转换为 number
    • Number
    • parseInt/parseFloat
  2. 隐式转换(浏览器内部默认要先转换为 number 再进行计算的)
    • isNaNMath方法
    • 数学运算(特殊情况:在出现字符串的情况下不是数学运算,是字符串拼接)
    • ==比较的时候,有些值需要转换为数字再进行比较
  3. 转为number类型的规则,在隐式转换需要转为number类型时,与以下规则一致:
    • valueOf() 判断其是否有原始值,没有则调用toString转为字符串,最后调用Number转为数字
    • 会转为0的情况
      • 空字符串'0'falsenull空数组
      • 数组中只有一个元素时,如果这个元素是空字符串'0'0nullundefined空数组
       Number('')//0
       Number('0')//0
       Number(null)//0
       Number(false)//0
       Number([])//0 valueOf() 判断其是否有原始值,没有=>toString()为''=>Number('')=>0
      
       Number(true)//1
       Number([1])//1 valueOf() 判断其是否有原始值,没有=>toString()为'1'=>Number('1')
      
      
       Number('10')//10
       Number('10px')//NaN
       Number(undefined)//NaN
       Number([1,2])//NaN valueOf() 判断其是否有原始值,没有=>toString()为'1,2'=>Number('1,2')
       Number(function(){})//NaN Number("function(){}")
       Number({})//NaN {}.toSting()=>"[object Object]"
      
    • bigint类型会转为 number 类型,并且失去精度
       Number(11111n)//11111 
      
    • symbol 类型不可转换为number类型
      Number(Symbol('11'))//报错
      
    • 关于parseIntisNaN
      • isNaN 检测数据类型时会把数据转为number 类型再判断
      • parseInt 会把数据先转为字符串,再查找字符串中是否有符合条件的数字,没有则返回NaN
    parseInt("")//NaN
    Number("")//0
    isNaN("")//false 0是有效数字
    parseInt(null)//NaN parseInt("null")
    Number(null)//0
    isNaN("12px")//true Number("12px")=>NaN
    parseFloat("1.6px") +parseInt("1.2px") +typeof parseInt(null)
    //1.6+1+ typeof NaN
    //1.6+1+"number"=>"2.6number"
    isNaN(Number(!!Number(parseInt("0.8"))))//false
    //parseInt("0.8")=>0
    //Number(0)=>0
    //!!0=>false
    //Number(false)=>0
    //isNaN(0)=>false
    typeof !parseInt(null) + !isNaN(null)//booleantrue
    //!parseInt(null)=>!NaN=>true
    //typeof true => "boolean"
    //isNaN(null) => false
    //!false => true
    
二、把其它数据类型转换为string类型
  1. 能使用的方法(都是调用其原型的toString)

    • toString()
    • String()
  2. 隐式转换(一般都是调用其 toString

    • 加号运算时,如果某一边出现字符串,则是字符串拼接
    • 字符串 == 对象 会把对象转为字符串比较
    • 把对象转换为数字,需要先toString()转换为字符串,再去转换为数字
    • 基于 alert/confirm/prompt/document... 这些方式输出内容,都是把内容先转换为字符串,然后再输出的
  3. 字符串拼接规则

    • 字符串拼接时,加号两边如果出现字符串或者引用类型的值({}[]function(){}),都会变成字符串拼接(因为原本应该是把引用类型的值转为数字,但是需要先转为字符串,遇到字符串就直接变成字符串拼接了)

      对象转为字符串 toString()

      {} => "[object Object]"  
      function(){}  =>"function(){}"
      {}+0;//0 没有变成字符串拼接的原因:把{}当做块处理了,不参与数学运算
      ({}+0);//"[object Object]0" 用括号运算符包起来就是数学运算了   
      

      数组转为字符串 toString,效果类似于join方法

      转为空字符串的情况:

      • 空数组
      • 数组中只有一个元素时,如果这个元素是空字符串nullundefined空数组
      [] =>""  
      [1] => "1"  
      [1,2] =>"1,2"
      [undefined]=> "" 
      [null]=>"" 
      
    • 字符串拼接时,基本数据类型转为字符串 调用String方法

      //字符串拼接时,基本数据类型转为字符串 String(value)
      false=>'false'
      null=>'null'
      undefined=>'undefined'
      111=>'11'//整数部分大于等于22位或者小数部分大于等于7位时,会得到科学记数法的字符串
      11n=>'11'//直接去掉 "n" 获得的数字字符串是准确的
      Symbol({})=>"Symbol([object Object])"//Symbol存储值时,是转为字符串存储的
      
    • 加号出现在字符串或者对象一边不是字符串拼接,是数学运算,如:++i+ii++

      var a="10"; ++a//11
      var b={}; ++b//NaN
      var c=[]; ++c//1  []=>''=>0=>0+1
      

    题目

    let result =10 + false +undefined+[]+'Tencent'+null+true+{};
    //(10+0+NaN)+''+'Tencent' +'null' +'true' + '[object Object]'
    //"NaNTencentnulltrue[object Object]" 
    console.log(result)
    
三、把其他数据类型转换为boolean类型
  1. 基于以下方式可以把其他数据类型转换为布尔
    • ! 转换为布尔类型后取反
    • !! 转换为布尔类型
    • Boolean
  2. 隐式转换
    • 在循环或者条件判断中,条件处理的结果就是布尔类型值
  3. 规则:只有 0NaN空字符串undefinednull 五个值会变为false,其余都是true
四、在==比较的过程中,数据转换的规则
  1. 「类型一样的几个特殊点」

    • {} == {} : false 说明:对象(引用类型的值)比较的是堆内存的地址
    • [] == [] : false 同上
    • NaN == NaN : false
  2. 「类型不一样的转换规则」

    • null == undefined : true
    • nullundefined其他任何值都不相等
    • 字符串 == 对象 要把对象转换为字符串
    • 剩下如果==两边数据类型不一致,都是需要转换为数字再进行比较 注意点:
      • 虽然Number(null)的结果是0,但是null0 ==比较时并不是转为数字比较的
    undefined==null//true
    undefined == '' //false
    undefined == 0//false	
    undefined == false //false
    undefined == [] //false
    undefined == {}//false
    
    字符串和引用类型值比较(引用类型转为字符串)
    'aaa'=={} //false {}.toString()=> '[object Object]'
    '0' == [] //false [].toString()=>''
    '0' == [0] //true [0].toString()=>'0'
    '1,2' == [1,2]//true [1,2].toString=>'1,2'
    'function(){}' == function(){}
    //true (function(){}).toString()=>'function(){}'
    
    其它的转为数字比较(调用Number0 == '' //true  Number('')=>0
    0 == false //true Number(false)=>0
    0 == {}// false Number({})=>Number("[object Object]")=>NaN
    0 == []// true Number([])=>Number('')=>0
    0 == [0]// true Number([0])=>Number('0')=>0
    0 == [0,1]// false Number([0,1])=>Number('0,1')=>NaN
    0 == [false]//false Number([false])=>Number('false')=>NaN
    0 == [undefined]//true Number([undefined])=>Number('')=>0
    0 == [null]//true Number([null])=>Number('')=>0