JS中,你不知道的20个Number类型属性和方法

前言

js中,Number类型是我们常用的数据类型之一,由于计算机的运算时常会产生浮点数,得到了我们认为本应该正确的数据,却产生了偏差,最经典的莫过于0.1+0.2!=0.3 ,这给我们带来了很大的困扰。js中为了解决这些问题,提供了一些方法和属性来解决这些问题,其中属性为8种,方法为12种

正文

Number属性

Number的属性均为静态属性,均不可写,不可枚举,不可配置

Number.EPSILON

表示1于大于1最小浮点数之间的差值

当我们打印这个属性时得到了2.220446049250313e-16,当小于这个差值的时候,就证明在运算过程中产生了较小的浮点差值,这个差值可以忽略不计,可以选择舍弃掉这个在运算中所产正的差值。

js 复制代码
//最为经典所会产生浮点差值的加法
const X = 0.1 + 0.2;//0.30000000000000004
//这里判断 所产生的差值较小这个最小差值
console.log(N - 0.3 < Number.EPSILON);//true

当然这个最小浮点差值是固定的,当产生大额数据运算时,这个差值就不适用了

js 复制代码
const X = 1000.1;
const Y = 1000.2;
const Z = 2000.3;

//这里看到当数字为10^3运算时,他的浮点差会大许多 从结果来说大约大了2000左右
console.log(X + Y);//2000.3000000000002

//这里再进行浮点最小差的时候需要再*2000
console.log(X - Z < 2000 * Number.EPSILON);//true

重点是:不要简单地将 Number.EPSILON 作为相等性测试的阈值。使用适合要比较的数字的数量级和精度的阈值。

Number.NaN

此属性等同于NaN,表示为一个非数字的值

js 复制代码
console.log(Number.NaN);//NaN

console.log(isNaN(Number.NaN));//true

Number.MAX_SAFE_INTEGER

该属性表示js中最大安全整数,如果超过这个整数,建议使用BigInt类型数据代替

js 复制代码
//打印这个属性得到值为安全最大正整数的值
console.log(Number.MAX_SAFE_INTEGER);//9007199254740991

const MAX1 = Number.MAX_SAFE_INTEGER + 1;
const MAX2 = Number.MAX_SAFE_INTEGER + 2;
console.log(MAX1, Number.MAX_SAFE_INTEGER);//9007199254740992 9007199254740991
console.log(MAX1 === MAX2);//true

这里不知道是js特性还是Number的属性特性,只有这个最大安全值在+1和+2的时候所得到值才是相等的,其余情况下均为不等

Number.MIN_SAFE_INTEGER

该属性表示js中最小安全整数,如果超过这个整数,建议使用BigInt类型数据代替

js 复制代码
//整体同最大安全正整数的值相同 只是取反值
console.log(Number.MAX_SAFE_INTEGER);//-9007199254740991

const MIN1 = Number.MIN_SAFE_INTEGER - 1;
const MIN2 = Number.MIN_SAFE_INTEGER - 2;
console.log(MIN1, Number.MIN_SAFE_INTEGER);//-9007199254740992 -9007199254740991
console.log(MIN1 === MIN2);//true

Number.MAX_VALUE

该属性表示js中最大的数值,如果超过这个数值将为Infinity

js 复制代码
console.log(Number.MAX_VALUE); //1.7976931348623157e+308

//这里使用加法是无法改得到这个改变的值的
console.log(Number.MAX_VALUE + 100000000000000000000);//1.7976931348623157e+308
console.log(Number.MAX_VALUE + 1);//1.7976931348623157e+308

//当使用乘法才会改变
console.log(Number.MAX_VALUE * 1);//1.7976931348623157e+308
console.log(Number.MAX_VALUE * 2);//Infinity

Number.MIN_VALUE

该属性表示js中最小的正数值 ,如果小于这个数值将为0

js 复制代码
//打印这个最小的正数值,得到一个非常小的小数,无限趋近于0
console.log(Number.MIN_VALUE);//5e-324

//当使用这个数加1或减1的时候就相当于在0的基础上操作
console.log(Number.MIN_VALUE - 1);//-1
console.log(Number.MIN_VALUE + 1);//1

//如果使用这个最小正数除以2,得到的结果则为0
console.log(Number.MIN_VALUE / 2);//0

Number.POSITIVE_INFINITY

该属性表示为正无穷大的值,也就是相当于Infinity

正无穷的规则:

  • 任何正值,包括 POSITIVE_INFINITY,乘以 POSITIVE_INFINITY 等于 POSITIVE_INFINITY
  • 任何负值,包括 NEGATIVE_INFINITY,除以 POSITIVE_INFINITY 等于 NEGATIVE_INFINITY
  • 任何正数除以 POSITIVE_INFINITY 都是正零。
  • 任何负数除以 POSITIVE_INFINITY 都是负零。
  • 零乘以 POSITIVE_INFINITY 等于 NaN
  • NaN 乘以 POSITIVE_INFINITY 等于 NaN
  • POSITIVE_INFINITY除以任何负值NEGATIVE_INFINITY都等于 NEGATIVE_INFINITY
  • POSITIVE_INFINITY,除以任何正值(除了 POSITIVE_INFINITY)都等于 POSITIVE_INFINITY
  • POSITIVE_INFINITY,除以 NEGATIVE_INFINITYPOSITIVE_INFINITY,都等于 NaN
  • Number.POSITIVE_INFINITY > x 对于任何不是 POSITIVE_INFINITY 的数字 x 都为真。

Number.NEGATIVE_INFINITY

该属性表示为负无穷大的值,也就是相当于-Infinity

负无穷的规则:

  • 任何正值,包括 POSITIVE_INFINITY,乘以 NEGATIVE_INFINITY 等于 NEGATIVE_INFINITY
  • 任何负值,包括 NEGATIVE_INFINITY,乘以 POSITIVE_INFINITY 等于 POSITIVE_INFINITY
  • 任何正值除以 NEGATIVE_INFINITY 都是负零。
  • 任何负值除以 NEGATIVE_INFINITY 都是正零)。
  • 零除以 NEGATIVE_INFINITY 等于 NaN
  • NaN 乘以 NEGATIVE_INFINITY 等于 NaN
  • NEGATIVE_INFINITY,除以任何负值(除了 NEGATIVE_INFINITY),都等于 POSITIVE_INFINITY
  • POSITIVE_INFINITY,除以任何正值(除了 POSITIVE_INFINITY,都等于 NEGATIVE_INFINITY
  • NEGATIVE_INFINITY,除以 NEGATIVE_INFINITYPOSITIVE_INFINITY,都等于 NaN
  • x > Number.NEGATIVE_INFINITY 对于任何不是 NEGATIVE_INFINITY 的数字 x 都为真。

Number方法

Number.isNaN()

接受一个参数,判断这个参数是否为NaN。它与isNaN作用类似,但它更为健硕,直接受Number类型的参数,否则返回falseisNaN则会将接受的参数强制转化为Number类型。

js 复制代码
//与isNaN对比  以下Number.isNaN 都将返回false

Number.isNaN("NaN");
Number.isNaN(undefined);
Number.isNaN({});
Number.isNaN("blabla");
Number.isNaN(true);
Number.isNaN(null);
Number.isNaN("37");
Number.isNaN("37.37");
Number.isNaN("");
Number.isNaN(" ");


//以下isNaN将会把参数强行转化为Number类型
isNaN("NaN"); // true
isNaN(undefined); // true
isNaN({}); // true
isNaN("blabla"); // true
isNaN(true); // false,强制转换为 1
isNaN(null); // false,强制转换为 0
isNaN("37"); // false,强制转换为 37
isNaN("37.37"); // false,强制转换为 37.37
isNaN(""); // false,强制转换为 0
isNaN(" "); // false,强制转换为 0

Number.parseInt()

此方法解析一个字符串的参数并按照一定基数返回整数。接收两个参数,第一个传入个字符串的数字字符,传入Number类型将会强制转化为字符串,第二个参数为你要制定的2-36之间Number类型的基数,返回一个整数。

js 复制代码
//此方法与parseInt方法相同
Number.parseInt === parseInt; // true

console.log(Number.parseInt(24.6));//24
console.log(Number.parseInt("24.6"));//24
console.log(Number.parseInt("24.6px"));//24
console.log(Number.parseInt("  24.6px"));//24
console.log(Number.parseInt("你好,世界"));//NaN 此方法无法解析汉字
console.log(Number.parseInt(null));//强制转化为字符串'null'这里肯定是无法解析的 所以未NaN
console.log(Number.parseInt(undefined));//强制转化为字符串'undefined'这里肯定是无法解析的 所以未NaN
console.log(Number.parseInt(2, 2));//NaN 当基数为2的时候 当前位上只有0或1的可能,所以填入2位NaN
console.log(Number.parseInt(5.4, 10));//10的基数 直接取整
console.log(Number.parseInt(10.4, 5));//当基数为5时,前面的参数为10时就等于5
console.log(Number.parseInt(18.4, 32));//这里基数为32,当为10时就是32,18就是32+8 所以结果为40
console.log(Number.parseInt(20.4, 32));//这里基数为32,当为10的倍数时,也就是基数的倍数,所以这里为64

Number.parseFloat()

此方法解析一个字符串并返回浮点数,接收一个字符串,如果不是字符串将强行转化为字符串。

js 复制代码
//此方法与parseFloat方法相同
Number.parseFloat === parseFloat; // true

//浮点数都知道,当为第一个字符串无法解析的时候,就为NaN,即使中间有数字可以解析,有空格将忽略
console.log(Number.parseFloat(24.6));//24.6
console.log(Number.parseFloat(null));//NaN
console.log(Number.parseFloat(undefined));//NaN
console.log(Number.parseFloat("24.6"));//24.6
console.log(Number.parseFloat("24.6px"));//24.6
console.log(Number.parseFloat("边框24.6px"));//NaN
console.log(Number.parseFloat("  24.6px"));//24.6
console.log(Number.parseFloat("你好,世界"));//NaN

Number.isFinite()

此方法判断接收的参数是否是一个有限的数,即不是Infinity-InfinityNaN。此方法与isFinite()相比就是接收的参数必须为Number类型,否则为false,而isFinite()方法会将参数强行转化为Number类型再进行判断。

js 复制代码
Number.isFinite(Infinity); // false
Number.isFinite(NaN); // false
Number.isFinite(-Infinity); // false

Number.isFinite(0); // true
Number.isFinite(2e64); // true

//对比
isFinite("0"); // true;强制转换为数字 0
Number.isFinite("0"); // false
isFinite(null); // true;强制转换为数字 0
Number.isFinite(null); // false

Number.isInteger()

此方法接收一个参数,判断这个参数是否为整数。在某些情况下看似小数的参数也会被判定为整数。例如浮点数小于Number.EPSILON的小数会被判定为整数。或者接近于Number.MAX_SAFE_INTEGER的数因为精度丢失的情况下,小数也会被认为是整数。

js 复制代码
Number.isInteger(0); // true
Number.isInteger(1); // true
Number.isInteger(-100000); // true
Number.isInteger(99999999999999999999999); // true

Number.isInteger(0.1); // false
Number.isInteger(Math.PI); // false

Number.isInteger(NaN); // false
Number.isInteger(Infinity); // false
Number.isInteger(-Infinity); // false
Number.isInteger("10"); // false
Number.isInteger(true); // false
Number.isInteger(false); // false
Number.isInteger([1]); // false

Number.isInteger(5.0); // true
Number.isInteger(5.000000000000001); // false
Number.isInteger(5.0000000000000001); // true,因为精度损失
Number.isInteger(4500000000000000.1); // true,因为精度损失

Number.isSafeInteger()

该方法判断参数是否为一个最大的安全整数。

js 复制代码
//必须为Number类型参数,否则为false
Number.isSafeInteger(3); // true
Number.isSafeInteger(2 ** 53); // false
Number.isSafeInteger(2 ** 53 - 1); // true
Number.isSafeInteger(NaN); // false
Number.isSafeInteger(Infinity); // false
Number.isSafeInteger("3"); // false
Number.isSafeInteger(3.1); // false
Number.isSafeInteger(3.0); // true
Number.isSafeInteger(Number.MAX_SAFE_INTEGER )//true
Number.isSafeInteger(Number.MAX_SAFE_INTEGER + 1)//false

toFixed()

原型方法,使用定点表示法来格式化数值。接收一个0-100的参数进行对小数点位数进行四舍五入格式化,由于使用的是定点表示法来进行四舍五入格式化,在极个别情况下得到的结果可能并不符合预期,原因是后一位的浮点原因。

js里,为什么5.225.toFixed(2)!=5.23 - 掘金 (juejin.cn)

js 复制代码
//正常情况下不论正负都是以四舍五入的方式进行格式化的
(1.3545).toFixed();//1
(1.3545).toFixed(3);//1.55
(-1.3545).toFixed(3);//-1.55
(1.3545).toFixed(101);//Error 当超过参数限定的值时,这里会报错

toExponential()

原型方法,使用指数表示法表示该数字的字符串。接收一个0-100的参数对数字进行小数格式化。效果规则同toFixed类似,只是返回的是指数表示法的字符串,并且在不穿参数时将返回原值的指数字符串。

js 复制代码
(1.3545).toExponential();//1.3545e+0
(1.3545).toExponential(3);//1.355e+0
(-1.3545).toExponential(3);//-1.355e+0
(1.3545).toExponential(101);Error

toPrecision()

原型方法,接收一个1-100的参数来对应相应的精度,返回指定精度表示该数字的字符串

js 复制代码
//从非0的数字开始精度添加
(1.3545).toPrecision();//1.3545
(1.3545).toPrecision(3);//1.35
(-1.3545).toPrecision(3);//-1.35
(100.456).toPrecision(5);//100.46
(100.456).toPrecision(10);//100.4560000
(0.000235).toPrecision(5);//0.00023500
(1.3545).toPrecision(101);//Error

toLocaleString()

原型方法,特定语言环境来格式化数字。接收两个参数,第一个为缩写语言代码,详情见locales (en-US),第二个参数为输出格式的对象,与 Intl.NumberFormat() 构造函数的 options (en-US) 参数相同

js 复制代码
const number = 123456.789;

// 德国使用逗号作为小数分隔符,分位周期为千位
console.log(number.toLocaleString("de-DE"));
// → 123.456,789

// 在大多数阿拉伯语国家使用阿拉伯语数字
console.log(number.toLocaleString("ar-EG"));
// → ١٢٣٤٥٦٫٧٨٩

// 印度使用千位/拉克(十万)/克若尔(千万)分隔
console.log(number.toLocaleString("en-IN"));
// → 1,23,456.789

// nu 扩展字段要求编号系统,e.g. 中文十进制
console.log(number.toLocaleString("zh-Hans-CN-u-nu-hanidec"));
// → 一二三,四五六.七八九

// 当请求不支持的语言时,例如巴厘语,加入一个备用语言,比如印尼语
console.log(number.toLocaleString(["ban", "id"]));
// → 123.456,789

toString() 和 valueOf()

原型方法,toSting方法返回该数字的字符串,接收一个参数,在2-36范围内的数字基数(也就是转进制),valueOf则是返回该数字的值,一般情况下在js内为隐式调用。

js 复制代码
//toString方法
console.log((31).toString());//'31'
console.log((31).toString(16));//'1f'
//toString也是会被隐式调用的,例如在模板字符串中
Number.prototype.toString = () => "重写了";
console.log(`${1}`); // "1"
console.log(`${new Number(1)}`); // "重写了"


//为了更清醒的看出valueOf被隐式调用,这里重写以下
Number.prototype.valueOf = function () {
  console.log(this, "隐式调用的valueOf");
  return this;
};
//这里必须时new出来的数字
const a = new Number(18);
console.log(a > 1);//当进项逻辑运算的时候,valueOf则会在此隐式调用
//[Number: 18] 隐式调用的valueOf
//true

最后

虽然在大多数场景下,js中Number类型的处理并没有操作并没有其他类型操作那般繁多,但是Number类型的操作也是常有的,例如在一些对数字比较敏感的场景下,需要对数字进行精准的操作。

在js中Number类型的方法和属性多数情况下足够我们安全的对数字进行操作,例如浮点数的精度问题可以使用Number.EPSILON属性来对那些我们认为较为比合理的浮点数进行处理等,某些场景下对于浮点数的精度问题最终还需要做一些更加谨慎的处理才行,这毕竟是计算机运算的一个通病!

相关推荐
@大迁世界7 分钟前
TypeScript 的本质并非类型,而是信任
开发语言·前端·javascript·typescript·ecmascript
GIS之路16 分钟前
GDAL 实现矢量裁剪
前端·python·信息可视化
是一个Bug19 分钟前
后端开发者视角的前端开发面试题清单(50道)
前端
Amumu1213821 分钟前
React面向组件编程
开发语言·前端·javascript
学历真的很重要22 分钟前
LangChain V1.0 Context Engineering(上下文工程)详细指南
人工智能·后端·学习·语言模型·面试·职场和发展·langchain
持续升级打怪中43 分钟前
Vue3 中虚拟滚动与分页加载的实现原理与实践
前端·性能优化
GIS之路1 小时前
GDAL 实现矢量合并
前端
hxjhnct1 小时前
React useContext的缺陷
前端·react.js·前端框架
冰暮流星1 小时前
javascript逻辑运算符
开发语言·javascript·ecmascript
前端 贾公子1 小时前
从入门到实践:前端 Monorepo 工程化实战(4)
前端