javascript之number

146 阅读10分钟

Number 值表示像 37 或 -9.25 这样的浮点数值。 Number 构造函数包含常量和处理数值的方法。其他类型的值可以使用 Number() 函数转换为数值。

在 JavaScript 代码中,像 37 这样的数值字面值是一个浮点值,而不是整数。在常见的日常使用中,没有单独的整数类型。(JavaScript 也有 BigInt 类型,但它不是为取代日常使用的 Number 而设计的。37 仍然是一个数值,而不是 BigInt。)

1.Number 强制转换

许多期望数值的内置操作是将它们的参数转换为数值(这在很大程度上就是为什么 Number 对象的行为与数值原始值相似的原因)。该操作可以总结如下:

  • 对于 Number 则总是返回自己
  • undefined变成了 NaN
  • null 变成了 0
  • true 变成了 1false 变成了 0
  • 空字符串或仅空格字符串转换为 0
Number("123"); // 123
Number("123") === 123; // true
Number("12.3"); // 12.3
Number("12.00"); // 12
Number("123e-1"); // 12.3
Number(""); // 0
Number(null); // 0
Number("0x11"); // 17
Number("0b11"); // 3
Number("0o11"); // 9
Number("foo"); // NaN
Number("100a"); // NaN
Number("-Infinity"); // -Infinity
const d = new Date("December 17, 1995 03:24:00");
console.log(Number(d));//这将输出 `819199440000`。

2.静态属性

Number.EPSILON

Number.EPSILON 属性表示 1 与Number可表示的大于 1 的最小的浮点数之间的差值。

EPSILON 属性的值接近于 2.2204460492503130808472633361816E-16,或者 2^-52

x = 0.2;
y = 0.3;
z = 0.1;
equal = (Math.abs(x - y + z) < Number.EPSILON);

Polyfill

if (Number.EPSILON === undefined) {
    Number.EPSILON = Math.pow(2, -52);
}
Number.MAX_SAFE_INTEGER

Number.MAX_SAFE_INTEGER 常量表示在 JavaScript 中最大的安全整数(maxinum safe integer)(2^53 - 1)。 MAX_SAFE_INTEGER 是一个值为 9007199254740991 的常量。因为 Javascript 的数字存储使用了 IEEE 754 中规定的双精度浮点数)数据类型,而这一数据类型能够安全存储 -(2^53 - 1) 到 2^53 - 1 之间的数值(包含边界值)。这里安全存储的意思是指能够准确区分两个不相同的值,例如 Number.MAX_SAFE_INTEGER + 1 === Number.MAX_SAFE_INTEGER + 2 将得到 true 的结果,而这在数学上是错误的

Number.MAX_SAFE_INTEGER // 9007199254740991
Math.pow(2, 53) - 1     // 9007199254740991
Number.MAX_VALUE

Number.MAX_VALUE 属性表示在 JavaScript 里所能表示的最大数值。 MAX_VALUE 属性值接近于 1.79E+308。大于 MAX_VALUE 的值代表 "Infinity"。 因为 MAX_VALUE 是 Number 对象的一个静态属性,所以你应该直接使用Number.MAX_VALUE ,而不是作为一个创建的 Number 实例的属性。

Number.MIN_SAFE_INTEGER

Number.MIN_SAFE_INTEGER 代表在 JavaScript 中最小的安全的 integer 型数字 (-(2^53 - 1))。MIN_SAFE_INTEGER 的值是-9007199254740991. 形成这个数字的原因是 JavaScript 在 IEEE 754中使用double-precision floating-point format numbers 作为规定。在这个规定中能安全的表示数字的范围在-(2^53 - 1) 到 2^53 - 1之间。

Number.MIN_SAFE_INTEGER // -9007199254740991
-(Math.pow(2, 53) - 1)  // -9007199254740991
Number.MIN_VALUE

Number.MIN_VALUE 属性表示在 JavaScript 中所能表示的最小的正值。MIN_VALUE 属性是 JavaScript 里最接近 0 的正值,而不是最小的负值。MIN_VALUE 的值约为 5e-324。小于 MIN_VALUE ("underflow values") 的值将会转换为 0。

Number.NaN

Number.NaN 表示“非数字”(Not-A-Number)。和 NaN 相同。 不必创建一个 Number 实例来访问该属性,使用 Number.NaN 来访问该静态属性。

Number.NEGATIVE_INFINITY

Number.NEGATIVE_INFINITY 属性表示负无穷大。 Number.NEGATIVE_INFINITY 的值和全局对象的 Infinity 属性的负值相同。该值的行为同数学上的无穷大(infinity)有一点儿不同:

  • 任何正值,包括 POSITIVE_INFINITY乘以 NEGATIVE_INFINITY 为 NEGATIVE_INFINITY
  • 任何负值,包括 NEGATIVE_INFINITY乘以 NEGATIVE_INFINITY 为 POSITIVE_INFINITY
  • 0 乘以 NEGATIVE_INFINITY 为 NaN.
  • NaN 乘以 NEGATIVE_INFINITY 为 NaN.
  • NEGATIVE_INFINITY 除以任何负值(除了 NEGATIVE_INFINITY)为 POSITIVE_INFINITY
  • NEGATIVE_INFINITY 除以任何正值(除了 POSITIVE_INFINITY)为 NEGATIVE_INFINITY
  • NEGATIVE_INFINITY 除以 NEGATIVE_INFINITY 或 POSITIVE_INFINITY 是 NaN
  • 任何数除以 NEGATIVE_INFINITY 为 0。

下例中,赋值给变量 smallNumber 一个明显小于 JavaScript 中的最小值的值。当 if 语句执行时,smallNumber 值为 "-Infinity",因此在继续执行代码前,smallNumber 被设为一个更容易管理的值。

var smallNumber = (-Number.MAX_VALUE) * 2

if (smallNumber == Number.NEGATIVE_INFINITY) {
 smallNumber = returnFinite();
}
Number.POSITIVE_INFINITY

Number.POSITIVE_INFINITY 属性表示正无穷大。 Number.POSITIVE_INFINITY 的值同全局对象 Infinity 属性的值相同。

该值的表现同数学上的无穷大有点儿不同:

  • 任何正值,包括 POSITIVE_INFINITY,乘以 POSITIVE_INFINITY 为 POSITIVE_INFINITY
  • 任何负值,包括 NEGATIVE_INFINITY,乘以 POSITIVE_INFINITY 为 NEGATIVE_INFINITY
  • 0 乘以 POSITIVE_INFINITY 为 NaN。
  • NaN 乘以 POSITIVE_INFINITY 为 NaN。
  • POSITIVE_INFINITY 除以 NEGATIVE_INFINITY 以外的任何负值为 NEGATIVE_INFINITY
  • POSITIVE_INFINITY 除以 POSITIVE_INFINITY 以外的任何正值为 POSITIVE_INFINITY
  • POSITIVE_INFINITY 除以 NEGATIVE_INFINITY 或 POSITIVE_INFINITY 为 NaN。
  • 任何数除以 POSITIVE_INFINITY 为 0。

下例中,赋值给变量 bigNumber 一个大于 JavaScript 中最大值的值。当 if 语句执行时,变量 bigNumber 值为 "Infinity",因此在继续执行代码前,为变量 bigNumber 设置一个容易管理的值。

var bigNumber = Number.MAX_VALUE * 2
if (bigNumber == Number.POSITIVE_INFINITY) {
 bigNumber = returnFinite();
}
Number.isFinite()

Number.isFinite()  方法用来检测传入的参数是否是一个有穷数。和全局的 isFinite() 函数相比,这个方法不会强制将一个非数值的参数转换成数值,这就意味着,只有数值类型的值,且是有穷的(finite),才返回 true

Number.isFinite(Infinity);  // false
Number.isFinite(NaN);       // false
Number.isFinite(-Infinity); // false

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

Number.isFinite('0');       // false, would've been true with
                            // global isFinite('0')
Number.isFinite(null);      // false, would've been true with
                            // global isFinite(null)
Number.isInteger()

Number.isInteger()  如果被检测的值是整数,则返回 true,否则返回 false。注意 NaN 和正负 Infinity 不是整数。

Number.isInteger(0);         // true
Number.isInteger(1);         // true
Number.isInteger(-100000);   // true

Number.isInteger(0.1);       // false
Number.isInteger(Math.PI);   // 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.isNaN()

在 JavaScript 中,NaN 最特殊的地方就是,我们不能使用相等运算符(== (en-US) 和 === (en-US))来判断一个值是否是 NaN,因为 NaN == NaN 和 NaN === NaN 都会返回 false。因此,必须要有一个判断值是否是 NaN 的方法。

和全局函数 isNaN() 相比,Number.isNaN() 不会自行将参数转换成数字,只有在参数是值为 NaN 的数字时,才会返回 true

Number.isNaN(NaN);        // true
Number.isNaN(Number.NaN); // true
Number.isNaN(0 / 0)       // true

// 下面这几个如果使用全局的 isNaN() 时,会返回 true。
Number.isNaN("NaN");      // false,字符串 "NaN" 不会被隐式转换成数字 NaN。
Number.isNaN(undefined);  // false
Number.isNaN({});         // false
Number.isNaN("blabla");   // false

// 下面的都返回 false
Number.isNaN(true);
Number.isNaN(null);
Number.isNaN(37);
Number.isNaN("37");
Number.isNaN("37.37");
Number.isNaN("");
Number.isNaN(" ");

Number.isSafeInteger()

返回值一个布尔值 表示给定的值是否是一个安全整数(safe integer)。

Number.isSafeInteger(3);                    // true
Number.isSafeInteger(Math.pow(2, 53))       // false
Number.isSafeInteger(Math.pow(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.parseFloat()

返回值给定值被解析成浮点数,如果无法被解析成浮点数,则返回NaN

Number.parseInt()

返回值从给定的字符串中解析出的一个整数.如果基数小于 2 或大于 36,或第一个非空白字符不能转换为数字,则返回 NaN

Number.parseInt === parseInt // true
Number.prototype.toExponential()

返回值一个用幂的形式 (科学记数法) 来表示Number 对象的字符串。小数点后以 fractionDigits 提供的值来四舍五入。如果 fractionDigits 参数被忽略了,小数点后的将尽可能用最多的位数来表示该数值。

对数值字面量使用 toExponential() 方法,且该数值没有小数点和指数时,应该在该数值与该方法之间隔开一个空格,以避免点号被解释为一个小数点。也可以使用两个点号调用该方法.

如果一个数值的小数位数多余 fractionDigits 参数所提供的,则该数值将会在 fractionDigits 指定的小数位数处四舍五入。可以查看 toFixed() 方法描述中关于四舍五入的讨论,同样应用于 toExponential() 方法。

var numObj = 77.1234;

alert("numObj.toExponential() is " + numObj.toExponential()); //输出 7.71234e+1

alert("numObj.toExponential(4) is " + numObj.toExponential(4)); //输出 7.7123e+1

alert("numObj.toExponential(2) is " + numObj.toExponential(2)); //输出 7.71e+1

alert("77.1234.toExponential() is " + 77.1234.toExponential()); //输出 7.71234e+1

alert("77 .toExponential() is " + 77 .toExponential()); //输出 7.7e+1
Number.prototype.toFixed()

返回值使用定点表示法表示给定数字的字符串。

一个数值的字符串表现形式,不使用指数记数法,而是在小数点后有 digits(注:digits 具体值取决于传入参数)位数字。该数值在必要时进行四舍五入,另外在必要时会用 0 来填充小数部分,以便小数部分有指定的位数。如果数值大于 1e+21,该方法会简单调用 Number.prototype.toString()并返回一个指数记数法格式的字符串。

var numObj = 12345.6789;

numObj.toFixed();         // 返回 "12346":进行四舍六入五看情况,不包括小数部分
numObj.toFixed(1);        // 返回 "12345.7":进行四舍六入五看情况

numObj.toFixed(6);        // 返回 "12345.678900":用 0 填充

(1.23e+20).toFixed(2);    // 返回 "123000000000000000000.00"

(1.23e-10).toFixed(2);    // 返回 "0.00"

2.34.toFixed(1);          // 返回 "2.3"

2.35.toFixed(1)           // 返回 '2.4'. Note it rounds up

2.55.toFixed(1)           // 返回 '2.5'. Note it rounds down - see warning above

-2.34.toFixed(1);         // 返回 -2.3(由于操作符优先级,负数不会返回字符串)

(-2.34).toFixed(1);       // 返回 "-2.3"(若用括号提高优先级,则返回字符串)

Number.prototype.toLocaleString()

返回一个语言环境下的表示字符串。

在使用 Intl.NumberFormat 的实现中,这与 new Intl.NumberFormat(locales, options).format(number) 调用等价。

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

通过 toLocaleString 返回的结果可以通过 options 参数进行定制:

const number = 123456.789;

// 要求货币格式
console.log(number.toLocaleString('de-DE', { style: 'currency', currency: 'EUR' }));
// → 123.456,79 €

// 日元不使用小数位
console.log(number.toLocaleString('ja-JP', { style: 'currency', currency: 'JPY' }))
// → ¥123,457

// 限制三位有效数字
console.log(number.toLocaleString('en-IN', { maximumSignificantDigits: 3 }));
// → 1,23,000

// 使用带选项的主机默认语言进行数字格式化
const num = 30000.65;
console.log(num.toLocaleString(undefined, {minimumFractionDigits: 2, maximumFractionDigits: 2}));
// → "30,000.65" 英语为默认语言
// → "30.000,65" 德语为默认语言
// → "30 000,65" 法语为默认语言
Number.prototype.toPrecision()

以定点表示法或指数表示法表示的一个数值对象的字符串表示,四舍五入到 precision 参数指定的显示数字位数。查看 Number.prototype.toFixed()方法关于四舍五入的讨论,同样应用于 toPrecision 方法。

如果忽略 precision 参数,则该方法表现类似于 Number.prototype.toString()。如果该参数是一个非整数值,将会向下舍入到最接近的整数。

let numObj = 5.123456

console.log(numObj.toPrecision())    // 输出 '5.123456'
console.log(numObj.toPrecision(5))   // 输出 '5.1235'
console.log(numObj.toPrecision(2))   // 输出 '5.1'
console.log(numObj.toPrecision(1))   // 输出 '5'

numObj = 0.000123

console.log(numObj.toPrecision())    // 输出 '0.000123'
console.log(numObj.toPrecision(5))   // 输出 '0.00012300'
console.log(numObj.toPrecision(2))   // 输出 '0.00012'
console.log(numObj.toPrecision(1))   // 输出 '0.0001'

// 请注意,在某些情况下可能会返回科学计数法字符串
console.log((1234.5).toPrecision(2)) // 输出 '1.2e+3'
Number.prototype.toString()

Number 对象覆盖了 Object 对象上的 toString() 方法,它不是继承的 Object.prototype.toString()。对于 Number 对象,toString() 方法以指定的基数返回该对象的字符串表示。

如果转换的基数大于 10,则会使用字母来表示大于 9 的数字,比如基数为 16 的情况,则使用 a 到 f 的字母来表示 10 到 15。

如果基数没有指定,则使用 10。

如果对象是负数,则会保留负号。即使 radix 是 2 时也是如此:返回的字符串包含一个负号(-)前缀和正数的二进制表示,不是 数值的二进制补码。

进行数字到字符串的转换时,建议用小括号将要转换的目标括起来,防止出错。

var count = 10;

console.log(count.toString());    // 输出 '10'
console.log((17).toString());     // 输出 '17'
console.log((17.2).toString());   // 输出 '17.2'

var x = 6;

console.log(x.toString(2));       // 输出 '110'
console.log((254).toString(16));  // 输出 'fe'

console.log((-10).toString(2));   // 输出 '-1010'
console.log((-0xff).toString(2)); // 输出 '-11111111'
Number.prototype.valueOf()

表示指定 Number 对象的原始值的数字

var numObj = new Number(10);
console.log(typeof numObj); // object

var num = numObj.valueOf();
console.log(num);           // 10
console.log(typeof num);    // number