Number数字类型

  1. 常规数字
  2. NaN(NOT A NUMBER):不是一个数,但是隶属于数字类型
  3. Infinity (无穷大值)

NaN和isNaN(检测一个值是否为非有效数字)方法

关于NaN

1.【NaN和任何值都不相等,甚至和自己都不相等;】

  1. NaN == NaN //false
  2. NaN === NaN //false
  3. NaN !== NaN //true

2.【但是用Object.is(NaN,NaN)判断两个值是否相等,结果是true】

isNaN:检测一个值是否是非有效数字

  • 如果【不是有效数字】则返回true
  • 反之【是有效数字】则返回false

在使用isNaN进行检测的时候,其机制将首先会验证检测的值是否为数字类型,如果不是,先基于Number()这个方法,把值转换为数字类型,然后再检测。

  • 如isNaN(‘10’); //为false,因为在检测前由于此机制,自动转型了
  • 凡是能够转成数字之后是有效数字的,都是有效数字
    1. //isNaN([val])
    2. console.log(isNaN(10));//false
    3. console.log(isNaN('AA'));//True
    4. /*
    5. 实际上在检测之前相当于发生了:
    6. Number('AA'); =>NaN 【转不成数字】
    7. isNaN(NaN); =>TRUE
    8. */
    9. //
    10. console.log(isNaN('10'));//false
    11. /*
    12. 类型转换机制
    13. 实际上在检测之前相当于发生了:
    14. Number('10'); =>10
    15. isNaN(10); =>false
    16. */
  1. isNaN('123') //false
  2. isNaN(123) // false
  3. isNaN(" ") //false
  4. isNaN('1.2.3') // true
  5. isNaN("23px") // true
  6. Number('"23px") = NaN
  7. isNaNNumber('aaa')) //true Number('aaa'") = NaN
  8. isNaN(Number(true)) // 输入1 =》false
  9. isNaN(Number(false)) // 输入0 =》false
  10. isNaN(Number(null)) // 输入0 =》false
  11. isNaN(Number(undefined)) // 输入NaN =》true

自增的特殊性

由于+号的特殊性质 【可代表数学运算】,【也可代表字符串拼接】 所以在i++; i+=n; i=i+n; 这三种运算形式中也有些微的差别。 i++;和其他两种不完全一样,其代表着纯粹的数学运算

  1. let i = '10';
  2. i=i+1;//=>'10'+1=>'101'【结果为字符串拼接】
  3. i+=1;//'10'+1=>'101'【结果为字符串拼接】
  4. i++;//=>10=>10+1=>11【结果为数字11,过程为数学运算】

把其他类型值转换为数字类型

两类方法:手动转换和隐式转换

隐式转换:【浏览器内部默认要先转换为Number再进行计算的】

  1. isNaN([val])
  2. ==数学运算(特殊情况:+在出现字符串或对象的情况下不是数学运算,而是字符串拼接)【只有前++/++后/+i的时候也可能是数学运算】
  3. ==进行比较的时候 一些情况下会将数据类型进行转换为数字

手动转换

Number([val]): 把所有有效数字字符都进行转换(一般用于浏览器的隐式转换中)

d
+ 规则:

1 把字符串转换为数字:空字符串变为0,(第一个点除外,其作为小数点存在)如果出现任何一个非有效数字字符,结果都是NaN
  1. console.log(Number('12.5'));//12.5
  2. console.log(Number('12.5px'));//NaN
  3. console.log(Number('12.5.5'));//NaN
  4. console.log(Number(''));//0

2 把布尔转换为数字:true->1 false->0
  1. console.log(Number(true));//1
  2. console.log(Number(false));//0
  3. //练习
  4. console.log(isNaN(false)); //Number(false) =>0(是有效数字) =>false
  5. console.log(isNaN(true)); //Number(true) =>1(是有效数字) =>false

3 null->0 undefined->NaN

null会转换为0 【null代表空对象指针,虽然代表没有,但是是有一个代表”空”的对象存在的,所以转换为Number应为0】undefined转换为NaN 【undefined代表未定义,未定义代表没有赋值,没有赋值就是”没有值”,”没有值”转换为Number的值就是NaN】

  1. console.log(Number(null)); //=>0 console.log(Number(undefined));//=>NaN
  2. console.log(isNaN(null)); //Number(null) =>0(是有效数字) =>false
  3. console.log(isNaN(undefined)); //Number(undefined) =>NaN(不是有效数字) =>true

4 Symbol无法转换为数字,会报错:Uncaught TypeError: Cannot convert a Symbol value to a number
  1. console.log(Number(Symbol("123")))
  2. //=>Uncaught TypeError: Cannot convert a Symbol value to a number

5 BigInt去除“n”(超过安全数字的,会按照科学计数法处理)
  1. console.log(Number(231n)) //=>231

6 把对象转换为数字:

普通对象、正则表达式对象、日期对象….转换为数字都是NaN 只有数组对象有可能转换为数字【数组也是对象类型的!】 【空数组转换为0】 只有一项值的数组才能最终转换为数值

  • 先调用对象的 Symbol.toPrimitive 这个方法,如果不存在这个方法
  • 再调用对象的 valueOf 获取原始值,如果获取的值不是原始值
  • 再调用对象的 toString 把其变为字符串
  • 最后再把字符串基于Number方法转换为数字
  1. Number({name:"xxx",age:5}) //=>NaN
  2. 1.=>({name:"xxx",age:5})[Symbol.toPrimitive] //=>undefined
  3. 2.=>({name:"xxx",age:5}).valueOf() //=>{name: "xxx", age: 5}
  4. 3.=>({name:"xxx",age:5}).toString() //=>"[object Object]"
  5. 4.=>Number("[object Object]") //=>NaN
  1. console.log(Number([]));//=>0
  2. Number([10]) //=>10
  3. 1.=>[10][Symbol.toPrimitive] //=>undefined
  4. 2.=>[10].valueOf() //=>[10]
  5. 3.=>[10].toString() //=>"10"
  6. 4.=>Number("10") //=>10
  1. Number([10,20,30]) //=>NaN

7 其他特殊转换的案例
  1. let time = new Date()
  2. Number(time) //=>1625126051393
  3. time[Symbol.toPrimitive] //=>ƒ [Symbol.toPrimitive]() { [native code] } 因为time有这个方法并且有3个参数 number / string / default 浏览器自己调用这个方法,会默认传递的实参值
  4. time[Symbol.toPrimitive]('number') //=>1625126051393
  5. dir(time)
  6. VM1101:1 Thu Jul 01 2021 15:54:11 GMT+0800 (中国标准时间)
  1. Number(new Number(10)) //=>10
  2. new Number(10) //=> Number {10} 输出一个对象 里面包含valueof()
  3. 1.=>new Number(10)[Symbol.toPrimitive] //=>undefined
  4. 2.=>new Number(10).valueOf() //=>10 找到后不在往下走

parseInt([val],[进制]) / parseFloat([val])的使用场景

  • 【注意:parseFloat不支持第二个参数!!!可以找浮点型数字】
  • 【注意:parseInt可以识别各种整数(int)格式,如:8进制,10进制,16进制,所以可以接收第二个参数表示要转换为多少进制】

    规则: [val]值必须是一个字符串,如果不是则先toString() 转换为字符串;然后从字符串左侧第一个字符开始找, 把找到的有效数字字符最后转换为数字「一个都没找到就是NaN」;遇到一个非有效数字字符,不论后面是否还有有效数字字符,都不再查找了; parseFloat可以多识别一个小数点

  1. parseInt("10") //=> 10
  2. parseInt("010") //=> 10
  3. parseInt("10px") //=> 10
  4. parseInt("px10px") //=> NaN
  5. Number('10px') //=> NaN
  6. parseInt("10PX10") //=> 10
  7. parseInt("10.55px") //=> 10
  8. parseInt(null) //=> NaN
  9. parseInt(undefined) //=> NaN
  10. parseInt(false);//=>NaN
  11. parseInt(true);//=>NaN 如果是boolean,null,undefined类型值,则都会返回NaN
  12. parseInt({}) //=>NaN
  13. parseInt([]) //=>NaN
  14. /*
  15. parseInt/parseFloat
  16. 如果是普通对象,则都会返回NaN
  17. ({}).toString() =>"[object object]"
  18. parseInt/parseFloat("[object object]") =>NaN
  19. ----------------------------
  20. [].toString() =>""//空字符串
  21. parseInt/parseFloat("") =>NaN
  22. */
  23. ----------------------------
  24. console.log(parseInt([12]));//=>12
  25. console.log(parseFloat([12.5]));//=>12.5
  26. console.log(parseInt([12,13]));//=>12

parseInt第二个参数 讲解—-经典面试题

  1. let arr = [27.2, 0, '0013', '14px', 123];
  2. arr = arr.map(parseInt);
  3. //array.map(function(currentValue,index,arr){}) js中map函数会依次处理数组中的每一个元素 并返回一个新的数组 对原来的数组不会影响
  4. console.log(arr)
  5. /!*
  6. parseInt(27.2,0)
  7. parseInt('27.2',10) -> '27' -> '27'看做10进制,转换为10进制 =>27
  8. parseInt(0,1) =>NaN -> 制不在取值范围内,=>NaN
  9. parseInt('0013',2)
  10. parseInt('0013',2) -> '001' -> '001'看做2进制(2以内的数)10进制 =>1
  11. 0*2^2 + 0*2^1 + 1*2^0
  12. parseInt('14px',3)
  13. parseInt('14px',3) -> '1' -> '1'看做3进制(3以内的数 4超出三进制范围),转换为10进制 =>1
  14. 1*3^0
  15. parseInt(123,4)
  16. parseInt('123',4) -> '123' -> '123'看做4进制(4以内的数),转换为10进制 =>27
  17. 1*4^2 + 2*4^1 + 3*4^0
  18. parseInt传递的第二个值是一个radix进制
  19. + radix不写或者写0,默认是10进制「如果第一个传递的字符串是以“0x”开始的,那么默认是16进制」
  20. + radix取值范围:2~36,不在这个范围内,处理的结果都是NaN
  21. + 在传递的字符串中,从左到右,找到符合radix进制的值{遇到不符合的则结束查找},把找到的值,看做radix进制,最后转换为10进制
  22. + 把其它进制的值转换为10进制:“按权展开求和”
  23. *!/