Number
数值种类
正数 与 浮点数(区别在一浮点数内存空间更大)
console.log('1 为整数');
console.log('1.2 为浮点数');
// 浮点数保存数值不精确原因:无法使用二进制来精确表示小数
console.log(0.1 + 0.2 !== 0.3); // true
// 保存浮点数占用内存空间是整数的二倍,ECMAScript 会不遗余力的将浮点数转为整数
console.log(1.0); // 1
进制
- 十进制 (默认)由 0123456789 组成
- 八进制 (0开头) 由 01234567 组成
- 十六进制 (0x开头) 由 0123456789ABCDEF 组成
console.log(070); // 56
console.log(078); // 78 以0开头,但后面数值超过八进制所含数字范围(0~7)按照10进制解析
console.log(0xA); // 10
数值范围
// 最小/大值
console.log(Number.MIN_VALUE); // 5e-324
console.log(Number.MAX_VALUE); // 1.7976931348623157e+308
// 无穷值
console.log(Number.POSITIVE_INFINITY);// Infinity
console.log(Number.NEGATIVE_INFINITY);// -Infinity
其他类型转为数字方式一:Number类型转换
字符串转数字规则:除代表正负的符号外,字符串中只要含有除第一个.之外的其他非数字字符,转换结果就是 NaN
引用数据类型转换过程
- 调用 valueOf()
- 调用 toString()
- 使用 Number() 对基本类型的转换规则
// -------------- Number()基本数据类型转换 --------------
console.log(Number(true)); // 1
console.log(Number(false)); // 0
console.log(Number(null)); // 0
console.log(Number(undefined)); // NaN
console.log(Number('')); // 0
console.log(Number('12')); // 12
console.log(Number('+1.2')); // 1.2
console.log(Number('-1.2')); // -1.2
console.log(Number('qw')); // NaN
// -------------- Number()引用数据类型转换 ---------------
var arr = [];
console.log('Number(arr) => ', Number(arr));
// 0. [] => []
// 1. [] => ''
// 2. '' => 0
console.log('Number([12]) => ', Number([12]));
// 0. [12] => [12]
// 1. [12] => '12'
// 2. '12' => 12
console.log('Number([12,23]) => ', Number([12,23]));
// 0. [12,23] => [12,23]
// 1. [12,23] => '12,23'
// 2. '12,23' => NaN
console.log('Number({name: 12}) => ', Number({name: 12}));
// 0. {name: 12} => {name: 12}
// 1. {name: 12} => '[object Object]'
// 2. '[object Object]' => NaN
console.log('Number(function(){}) => ', Number(function(){}));
// 0. function(){} => f (){}
// 1. f (){} => 'function(){}'
// 2. 'function(){}' => NaN
console.log('Number(function test(i){return i}) => ', Number(function test(i){return i}));
// 0. function test(i){return i} => ƒ test(i){return i}
// 1. ƒ test(i){return i} => 'function test(i){return i}'
// 2. 'function test(i){return i}' => NaN
引用数据类型转数字详解(可跳过)
- 重写 valueOf()
/**
* 只重写 valueOf()方法
* 结果表明会调用 valueOf()方法
*/
var temp = {name: 12};
console.log('重写 temp.valueOf() 前=> ', temp.valueOf());
// temp.valueOf = function(){return '12'}; // 第一次
temp.valueOf = function(){return '1.2.1'}; // 第二次
// console.log('isNaN(temp.valueOf()) => ', isNaN(temp.valueOf()));
console.log('重写 temp.valueOf() 后=> ', temp.valueOf());
console.log('Number(temp) => ', Number(temp)); // 第一次 12 第二次 NaN
- 重写 toString()
/**
* 只重写 toString()方法
* 结果表明不论是在原型上定义还是在对象上定义都会调用 toString()方法
*/
var temp = {name: 12};
console.log('重写 temp.toString() 前=> ', temp.toString());
// temp.toString = function(i){return 2}; // 第一次
temp.toString = function(i){return '2..'}; // 第二次
// temp.__proto__.toString = function(j){return 2};
// temp.__proto__.toString = function(j){return '2..'};
console.log('重写 temp.toString() 后=> ', temp.toString());
console.log('Number(temp) => ', Number(temp)); // 第一次 2 第二次 NaN
- 同时重写 valueOf() 和 toString()
- valueOf() 的结果是引用数据类型本身
- toString() 通常是字符串包裹引用数据类型本身
- 不重写 valueOf() 方法,会调用原型上的 valueOf() 方法,得到引用类型,由于是引用类型,所以调用 toString(),得到结果
- 不重写 toString() 得到 12
- 重写 temp._proto_.toString 得到 3
- 在上述基础上 重写 temp.toString 得到 2
- 重写 valueOf() 方法,返回基本数据类型,得到 13,即不走 toString()
- 重写 valueOf() 方法,返回 [] / {} / function(){},得到 2,即走了 toString(),而且是对象私有的 toString()
/**
* 引用数据类型转为数字类型时,Number() 的转化规则是:
* 先调用 valueOf(),如果 valueOf() 返回的是基本数据类型,则按照基本数据类型转为 Number()规则转换并返回。
* 如果 valueOf() 返回引用数据类型,则会去调用该引用数据类型的 toString()方法得到结果,结果再按照基本数据
* 类型转为 Number() 规则进行转换。若重写 toString,使其返回引用类型会报错
*/
// var temp = {name: 12};
var temp = [12];
console.log('重写 temp.valueOf() 前=> ', temp.valueOf());
// valueOf 返回结果是基本数据类型,就不会再走 toString()
temp.valueOf = function(){return '13..'};
// valueOf 返回结果是引用数据类型,就会走 toString()
// temp.valueOf = function(){return []};
// temp.valueOf = function(){return {}};
// temp.valueOf = function(){return function(){}};
// console.log('isNaN(temp.valueOf()) => ', isNaN(temp.valueOf()));
console.log('前 temp.toString() => ', temp.toString());
// temp.toString = function(i){return 2};
// temp.toString = function(i){return []}; // Cannot convert object to primitive value
temp.__proto__.toString = function(j){return 3};
console.log('后 temp.valueOf() => ', temp.valueOf());
console.log('后 temp.toString() => ', temp.toString());
console.log('Number(temp) => ', Number(temp));
其他类型转为数字方式二:parseInt()、parseFloat()
按照字符串从左到右查找,从左到右依次查找有效数字,直到遇到一个非有效数字停止查找(不管后方是否还有,都不再查找)把找到的当做数字返回,(传递的值一定是字符串,不是字符串的转换成字符串然后继续执行查找)
// parseInt 转化成一个 int 数字
console.log('parseInt() ==>', parseInt()); // NaN
console.log('parseInt(+1) ==>', parseInt(+1)); // NaN
console.log('parseInt(-1) ==>', parseInt(-1)); // NaN
console.log('parseInt(" 12.3") ==>', parseInt(' 12.3')); // 排除空格 12
console.log('parseInt(" 12.9ADS") ==>', parseInt(' 12.9ADS')); // 读到其他字符结束 12
console.log('parseInt(070) ==>', parseInt(070)); // 八进制 56
console.log('parseInt(0xA) ==>', parseInt(0xA)); // 十六进制 10
// 按照指定进制解析
console.log('parseInt("10", 2) ==>', parseInt('10', 2)); // 2
console.log('parseInt("10", 8) ==>', parseInt('10', 8)); // 8
console.log('parseInt("10", 10) ==>', parseInt('10', 10)); // 10
console.log('parseInt("10", 16) ==>', parseInt('10', 16)); // 16
// 转换 Float类型 (1.只支持十进制 2.是整数会返回整数,而不是浮点数)
console.log('parseFloat("10.2ab") ==>', parseFloat("10.2ab")); // 10.2
console.log('parseFloat("0xA") ==>', parseFloat("0xA")); // 0
console.log('parseFloat("10.0") ==>', parseFloat("10.0")); // 10
console.log('parseFloat("1.234e3") ==>', parseFloat("1.234e3")); // 1.234
Number() 与 parsexxx()
- 处理机制不同
- Number() 走 V8 引擎设定的规则
- parseInt()/parseFloat() 走自己写的方法 (先转成字符串,然后一位一位的查找)
其他类型转为数字方式三:隐式转换
利用算术运算符转换为数字
'12' - 0; // 12
['14'] - 5; // 9
1 * '3'; // 3
'3' / 1; // 1
NaN(Not a Number)
这个值用于表示一个本来要返回数值的操作数未返回数值的情况(这样就不会报错了)
isNaN()
- 来源:
// 由于 NaN 不等于 NaN,所以不能通过等于 NaN 判断一个数是不是有效数字
console.log('NaN == NaN => ', NaN == NaN); // false
- 规则
- 如果是数字,直接返回 false
- 如果不是 isNaN() 将采用 Number() 函数转换规则进行转换
console.log('isNaN(12) => ', isNaN(12)); // 本身就是数字
console.log('isNaN(NaN) => ', isNaN(NaN)); // 本身就不是数字
console.log('isNaN(\'12\') => ', isNaN('12')); // 字符串 可以转为数字
console.log('isNaN(\'12qw\') => ', isNaN('12qw')); // 字符串 不能转为数字
console.log('isNaN(null) => ', isNaN(null)); // null 可以转数字
console.log('isNaN(undefined) => ', isNaN(undefined)); // undefined 转为 NaN
// isNaN() 转换引用类型过程 同 Number()
// 1.调用 valueOf()
// 2.调用 toString()
// 3.使用 Number() 对基本类型的转换规则
console.log('isNaN([\'+12.23\']) => ', isNaN(['+12.23']));
// 0. ['+12.23'] => ['+12.23']
// 1. ['+12.23'] => '+12.23'
// 2. isNaN('+12.23') => isNaN(12.23) => false
console.log('isNaN([12, 23]) => ', isNaN([12, 23]));
// 0. [12, 23] => [12, 23]
// 1. [12, 23] => '12, 23'
// 2. isNaN('12, 23') => true