《重学JavaScript 》之 你真的了解number数据类型吗?

212 阅读4分钟

概述

number 类型包括
(1)正数、0、负数、小数(浮点数)
(2)NaN:不是一个有效数字
(3)Infinity : 无穷大的值
(4)-Infinity; // 负无穷大的值

typeof -1         //=> "number"
typeof 0          //=> "number"
typeof 1          //=> "number"
typeof 1.2        //=> "number"
typeof NaN        //=> "number"
typeof Infinity    //=> "number"
typeof -Infinity   //=> "number"

一、 NaN 非有效数字类型

NaN 表示一个非有效数字(number)类型
NaN和任何值都不相等,包括本身

NaN == .....  //=> false
NaN == NaN    //=> false

二、把其他类型的数据转换成number类型

js 什么时候会把其他数据类型转换成数字number类型(常见)?
(1) Number()
(2) isNaN() (3) parseInt()
(4) parseFloat()
(5) == 比较-先执行Number()在比较(一个数字字符串、[数字]、true 和一数字比较式)
(6) 数学运算 (- / * %)“注意 + 除外”

1、 Number([value]) 返回值:NaN 或 有效数字,规则如下

(1)Number([String])

/**
  1、一旦字符串中出现非有效数字字符,则结果为NaN
  2、只有当字符串中全都是有效数字时,才能转换成具体的数字
  3、空字符串”转换为0
*/
Number('123')     //=> 123
Number('12.5')    //=> 12.5
Number('12.5.0')  //=> NaN
Number('')       //=> 0
Number('12px')    //=> NaN

(2)Number([Boolean])

Number(true)  //=> 1
Number(false) //=> 0

(3)Number([空值])

Number(null) //=> 0
Number(undefined)  //=> NaN

(4)Number([Symbol])

Symbol 类型不能转换为number类型

Number(Symbol(1)) 
// TypeError: Cannot convert a Symbol value to a number

(5)Number([对象])

先把对象转换成字符串 ==> 再把字符串转化为number类型

/**
  Number([String])
  1、一旦字符串中出现非有效数字字符,则结果为NaN
  2、只有当字符串中全都是有效数字时,才能转换成具体的数字
  3、空字符串”转换为0
*/
Number({})
// {}.toString() ==> "[object Object]" ==> Number("[object Object]") ==> NaN

Number([])    //=> 12.5
// [].toString() ==> "" ==> Number("") ==> 0

Number([10])
// [10].toString() ==> "10" ==> Number("10") ==> 10

 Number([10, 20, 30])
// [10, 20, 30].toString() ==> "10 , 20 ,30" ==> Number("10 , 20 ,30") ==> NaN

Number(["10px"])
// ["10px"].toString() ==> "10px" ==> Number("10px") ==> NaN


Number("abc")
// ["abc"].toString() ==> "abc" ==> Number("abc") ==> NaN

Number([function(){}]) 
// function(){}.toString() ==> "function (){}"  ==> Number("function (){}") ==> NaN

Number('12px')    //=> NaN

2、 isNaN([value]) 判断一个值是否为一个非有效数字

检测规则:当发现value不是number类型的值是,会通过Number()将其强制转换成number类型,再进行判断

isNaN(1) 		 //=> false 
isNaN(Infinity) //=> false 
isNaN("")       //=> false 
isNaN(NaN)      //=> true 

isNaN('aa') 
// Number('aa') => NaN => isNaN(NaN) => true

isNaN('12.5') 
// Number('12.5') => 12.5 => isNaN(12.5) => false

isNaN('12.5px') 
// Number('12.5px') => NaN => isNaN(NaN) => true

isNaN([]) 
// Number([]) => [].toString() => '' => Number('') => 0 => isNaN(0) => false

isNaN([10]) 
// Number([10]) => [10].toString() => '10' => Number('10') => 10 => isNaN(10) => false

isNaN([10,20]) 
// Number([10,20]) => [10,20].toString() => '10,20' => Number('10,20') => NaN => isNaN(NaN) => true

isNaN({}) 
// Number({}) => {}.toString() => '[object Object]' => Number[object Object]') => NaN => isNaN(NaN) => true

isNaN(null) 
// Number(null) => 0 => isNaN(0) => false

isNaN(undefined) 
// Number(undefined) => NaN => isNaN(NaN) => true

//isNaN(Symbol(1)) 
// Number(Symbol(1)) => TypeError 语法错误

3、 parseInt() && parseFloat()

(1)也是把其他类型转换成number类型
(2)处理原理和Number()不一样:如果处理的值是字符串,会从字符串最左侧开始查找,一直查找,到一个非有效数字字符为止
(3)parseInt/parseFloat(对象、数组、函数、nul、undefined、Boolean、" ") => NaN
(4)parseFloat() 就是比 parseInt() 多识别一个小数点(浮点类型)罢了,其余都一样

parseInt('12px') //=> 12
parseInt('12.5px') //=> 12
parseInt('12px15') //=> 12
parseInt('width:12px') //=> NaN
parseInt(undefined) //=> NaN
parseInt(null) //=> NaN
parseInt(true) //=> NaN
parseInt(false) //=> NaN
parseInt("") //=> NaN

parseFloat('12px') //=> 12
parseFloat('12.5px') //=> 12.5
parseFloat('12px15') //=> 12
parseFloat('width:12px') //=> NaN
parseFloat(undefined) //=> NaN
parseFloat(null) //=> NaN
parseFloat(true) //=> NaN
parseFloat(true) //=> NaN
parseFloat(false) //=> NaN
parseFloat("") //=> NaN

4、 == 比较运算符

如果 == 两边有非数字类型则先执行Number(),再比较(一个数字字符串、[数字]、true 和一数字比较式)

1 == "1"
// Number("1") => 1 => 1 == 1 => true

0 == ""
// Number("") => 0 => 0 == 0 => true

1 == true
//=> Number(true) => 1 => 1 == 1 => true

"1" == true
// 左侧:Number("1") => 1
// 右侧:Number(true) => 1
//  1 == 1 => true

0 == false
// Number(false) => 0 => 0 == 0 => true

0 == []
// Number([]) => [].toString() => "" =>  Number("") == 0 => 0 == 0 => true

1 == [1]
// Number([1]) => [1].toString() => "1" =>  Number("1") == 1 => 1 == 1 => true

1 == ["1"]
// Number(["1"]) => ["1"].toString() => "1" =>  Number("1") == 1 => 1 == 1 => true

"1" == ["1"]
// 左侧:Number("1") => 1
// 右侧:["1"].toString() => "1"
// 1 == 1 => true

5、 数学运算 (- / * %)

注意 如果运算两侧出现字符串类型变量时,“ + ” 无法正确进行数学运算,执行字符串累加规则
如果 “ 数学运算 ” 两边有非数字类型则先执行Number()再运算

1 + true
// 右侧:Number(true) => 1
// 1+1 => 2

1 + false
// 右侧:Number(false) => 0
// 1+0 => 1

1 - "1"
// 右侧:Number("1") => 1
// 1-1 => 0 

1 + "1"
// "11"

1 / "1"
// 右侧:Number("1") => 1
// 1/1 => 1 

2 * "3"
// 右侧:Number("3") => 3 
// 2*3 => 6

2 / 0
// Infinity

 "1" + ["1"]
// 左侧:"1"
// 右侧:Number([1]) => [1].toString() => Number("1") => 1
// "1"+1 => "11" 

 3 / [2]
// 右侧:Number([2]) => [2].toString() => Number("2") => 2
// 2/2 => 1.5

2 * [2]
// 右侧:Number([1]) => [2].toString() => "2" => Number("2")
// 2*2 => 4

面试真题,玩一下

1isNaN(Number(parseInt(0.8))) 
// step1 => parseInt(0.8) => 0
// step2 => Number(0) => 0
// step3 => isNaN(0) => false
// 最终结果:false2Number(isNaN(Number([false]))) 
// step1 => Number([false]) => [false].toString() => "false"
// step2 => isNaN("false") => true
// step3 => Number(true) => 1
// 最终结果:1