2515 字
13 分钟
JS数据类型-Number类型
2020-09-03
无标签

前言#

最近在做题目LeetCode表示数值的字符串这道题的时候 对数值类型又有了新的认识 打算重新总结下

1. 整数、浮点数#

JavaScript 内部,所有数字都是以64位浮点数形式储存,即使整数也是如此。所以,1与1.0是相同的,是同一个数 1 === 1.0 // true

保留两位小数#

1 四舍五入#

var num = 2.446242342
num = num.toFixed(2) // 输出是字符串 需要用parseFloat或Number再转一下

2 不四舍五入#

Math.floor(15.7784514000 * 100) / 100 // 15.77

2. 数值的进制#

  • 十进制:没有前导0的数值

  • 八进制:有前缀0o或0O的数值,或者有前导0、且只用到0-7的八个阿拉伯数字的数值

    012 // 10
    0o12 // 10
    0O12 // 10
    078 // 78 超出范围 无效的八进制 解析为十进制
  • 十六进制:有前缀0x或0X的数值

    0xA // 10
    0x12 // 18
    0XAB //171
  • 二进制:有前缀0b或0B的数值

    0b111 // 7
    0B11 // 3

默认情况下,JavaScript 内部会自动将八进制、十六进制、二进制转为十进制

3. 进制之间的转换#

1) Number.prototype.toString([radix])#

toString() 方法返回指定 Number 对象的字符串表示形式。 radix 指定要用于数字到字符串的转换的基数(从2到36)。如果未指定 radix 参数,则默认值为 10。

(12).toString() // "12" 十进制转十进制
(012).toString() // "10" 八进制转十进制
(10).toString(2) // "1010" 十进制转二进制
(0b1010).toString(8) // "12" 二进制转八进制

toString()以后是字符串格式 在通过格式转换 转为数值类型就好啦 怎么转换,后续有介绍哦

2) parseInt(string,[radix])#

parseInt() 可以将任意进制的数转为10进制

parseInt(111,2) // 3
parseInt(12,8) // 10
parseInt(0xA) // 10
parseInt(014) // 12

关于parseInt()的详细解释在后面

4. Number() 函数#

在说NaN 之前先说下Number函数

Number() 函数是数值类型的构造函数 同时也可以将其他类型转为数值类型 如果无法转为数值 就返回NaN

Number()函数的转换规则如下

  • Boolean false => 0 true => 1

  • Number 直接返回

  • null => 0

  • undefined => NaN

  • 字符串 1 空字符串转为0 2 只包含数字(包含前导正负号) 将其转为十进制 3 如果包含有效的进制格式 将转为相同大小的十进制 4 如果包含有效的浮点格式 将其转为对应的浮点数值 5 如果不符合以上条件 返回NaN

  • 对象 调用对用的valueOf()方法 然后按照前面的规则进行转换 如果转换的结果是NaN 则调用对象的toString()方法,然后再依照前面的规则进行转换

    Number(false) // 0 布尔值false对应0
    Number(123) // 123 数值类型直接返回
    Number(null) // 0
    Number(undefined) // NaN
    Number('') // 0
    Number('abc') // NaN 'abc' 不能被转为数字
    Number('123') // 123 '123' 可以被转为数字
    Number('123a) // NaN '123a' 不是只包含数字不能被转换
    Number('0x12') // 18 0x12是有效的进制格式 站位10进制
    Number('1.1') // 1.1 有效的浮点格式 转为相应的浮点格式
    Number([]) // 0 因为[].toString() ==> '' Number('') ==> 0
    Number([2]) // 2 因为[2].toString() ==> '2' Number('2') ==> 2
    Number([1,2,3]) // NaN [1,2,3].toString() ==> '1,2,3' 不能转为数值
    Number({}) // NaN ({}).toString() ==> "[object Object]" 不能转为数值

所以对于leetCode 这道题我们可以利用Number()函数对于字符串的转换规则 如果结果是NaN 就不符合条件 否则就是可以转为数值的字符串

var isNumber = function (s) {
s = s.trim()
if (s == '') return false // 因为 Number('') === 0 所以需要做特殊判断
return !isNaN(Number(s))
}

5. NaN#

NaN 表示“非数字”(Not a Number) 是一个特殊的数值 数据类型依然属于Number

  • 主要出现在将字符串解析成数字出错的场合
  • 一些数学函数的运算结果会出现NaN 比如 0除以0也会得到NaN
  • NaN不等于任何值,包括它本身

针对NaN的特性 ES定义了isNaN()函数 该函数接受一个参数 可以为任何类型 isNaN()会尝试将这个参数转为数值 转换规则与Number()函数一致 所以isNaN方法可以用来判断一个值是否 “不是数值”

NaN === NaN // false
isNaN(NaN) // true
isNaN(123) // false
// isNaN()只对数值有效,如果传入其他值,会先转成数值类型
isNaN('') // false
isNaN('hello') // true
//相当于
isNaN(Number('hello')) //true
isNaN(false) // false false会转为0
isNaN({}) //true
isNaN([1,2]) //true
// 所以isNaN() 为true的时候,有可能是一个字符串,或对象或数组
// 所以使用isNaN()时,需要先判断下数据类型
// 但是当数组为空,或数组长度为1时返回false
isNaN([]) //false
isNaN([1]) //false

由于isNaN()函数会对参数进行转换 那这题又可以直接写为

var isNumber = function (s) {
s = s.trim()
if (s == '') return false // 因为 Number('') === 0 所以需要做特殊判断
return !isNaN(s)
}

6. parseInt()#

parseInt()解析一个字符串并返回指定基数的十进制整数, radix 是2-36之间的整数,表示被解析字符串的基数。 如果不能解析的话返回NaN

parseInt 参数#

parseInt(string,[radix]) 接受两个参数

  • string 如果参数不是字符串类型 会通过toString()方法转为字符串
  • radix 从2-36 表示字符串的基数 需要注意的是 10不是默认值

如果 radix 是 undefined、0或未指定的,JavaScript会假定以下情况:

  • 如果输入的 string以 “0x”或 “0x”(一个0,后面是小写或大写的X)开头,那么radix被假定为16,字符串的其余部分被当做十六进制数去解析。
  • 如果输入的 string以 “0”(0)开头, radix被假定为8(八进制)或10(十进制)。具体选择哪一个radix取决于实现。ECMAScript 5 澄清了应该使用 10 (十进制),但不是所有的浏览器都支持。因此,在使用 parseInt 时,一定要指定一个 radix。
  • 如果输入的 string 以任何其他值开头, radix 是 10 (十进制)。
parseInt(110,2) // 6 二进制110 转为十进制是 6
parseInt(123,8) // 83 八进制的123 转为十进制是83
parseInt(89,8) // NaN 不是合法的八进制
parseInt('014') // 14 被当做十进制解析
parseInt(014) // 12 因为(014).toString() => 12

一道有意思的面试题#

["1", "2", "3"].map(parseInt) // [1,NaN,NaN]
// 相当于parseInt(1,0) => 1 string不以任何其他值开头 radix为十进制 parseInt(1,10) => 1
// parseInt(2,1) => NaN 1进制不合法 所以返回NaN
// parseInt(3,2) => NaN 3 是不合法的二进制 所以返回NaN

parseInt 忽略后续字符#

如果 parseInt 遇到的字符不是指定 radix 参数中的数字,它将忽略该字符以及所有后续字符,并返回到该点为止已解析的整数值。 parseInt 将数字截断为整数值。 允许前导和尾随空格。

parseInt('123a',2) // 1 因为符合二进制的只有1
parseInt('1123110',2) // 3 符合二进制的只有前面的11 找到2不符合 会忽略后面的字符 解析为十进制为3
parseInt('123abc') // 123 这通常用来在字符串中提取前面的数值

7. parseFloat()#

parseFloat() 函数解析一个参数(必要时先转换为字符串)并返回一个浮点数。

  • 如果 parseFloat 在解析过程中遇到了正号(+)、负号(- U+002D HYPHEN-MINUS)、数字(0-9)、小数点(.)、或者科学记数法中的指数(e 或 E)以外的字符,则它会忽略该字符以及之后的所有字符,返回当前已经解析到的浮点数。
  • 第二个小数点的出现也会使解析停止(在这之前的字符都会被解析)。
  • 参数首位和末位的空白符会被忽略。
  • 如果参数字符串的第一个字符不能被解析成为数字,则 parseFloat 返回 NaN。
  • parseFloat 也可以解析并返回 Infinity。
  • parseFloat解析 BigInt 为 Numbers, 丢失精度。因为末位 n 字符被丢弃。
// 以下的栗子全部返回3.14
parseFloat(3.14);
parseFloat('3.14');
parseFloat(' 3.14 ');
parseFloat('314e-2');
parseFloat('0.0314E+2');
parseFloat('3.14some non-digit characters');
parseFloat({ toString: function() { return "3.14" } });

8. 其他类型转换为数值类型#

有三个函数可以将非数值转为数值类型: Number() parseInt() parseFloat() 这三个函数对于同样的输入会返回不同的类型

方法1 Number()#

转换规则上面已说过

Number('1') // 1
Number('1.123') // 1.123
Number('1.abc') // NaN
Number('') // 0
Number(true) // 1
Number(false) // 0
Number(null) // 0
Number(undefined) // NaN
Number({a:1}) // NaN

方法2 parseInt()#

parseInt() 主要是将字符串转为整数 它会从第一个字符开始,直到不是数字结束

parseInt('1') //1
parseInt('1.23') // 1
parseInt(' 123') // 123
parseInt('1234abc') // 1234
parseInt('abc') // NaN
parseInt('a567bc') // NaN
parseInt(true) // NaN
parseInt(null) // NaN
parseInt(undefined) // NaN
parseInt({a:1}) // NaN
parseInt([1,2,3]) // 1

方法3 parseFloat()#

parseFloat() 主要是将字符串转为浮点数

parseFloat('3.14') // 3.14
parseFloat('314e-2') // 3.14
parseFloat('0.0314E+2') // 3.14
// 其他与parseInt()结果相同

方法4 - 0#

'1' - 0 // 1
'1.23' - 0 // 1.23
'1.abc' -0 // NaN
'' - 0 // 0
true -0 // 1
false - 0 // 0
null - 0 // 0
undefined - 0 // NaN
({a:1}) - 0

方法5 取正#

+ '1' // 1
+ '1.23' // 1.23
+ '1.abc' // NaN
+ '' // 0
+ true // 1
+ false // 0
+ null // 0
+ undefined // NaN
+ {a:1} // NaN

9. 补充一个比较运算符的坑#

不同类型#

比较不同类型的数据也许会出现不可预料的结果。 如果将字符串与数字进行比较,那么在做比较时 JavaScript 会把字符串转换为数值。 空字符串将被转换为 0 非数值字符串将被转换为始终为 false 的 NaN。

' ' >= 0 && ' ' <= 9 // true 因为空字符串会转为0
'a' >= 0 || 'a' <= 9 // false 'a' 转为数值 NaN
'123a' >= '123' // false '123a'也会转为NaN

相同类型都为字符串#

字符串大小会按照字母排序

'2' > '12' // true
'2020-6-8' > '2020-6-14' // true 因为 '8' > '14'
// 所以时间格式比较日期格式要yyyy-MM-dd去比较
'2020-06-08' > '2020-06-14' // false '08' < '14'
JS数据类型-Number类型
https://blog.cxyxiaoyu.top/posts/js数据类型-number类型/
作者
小宇
发布于
2020-09-03
许可协议
CC BY-NC-SA 4.0