侧边栏壁纸

JavaScript ES6 数值的拓展

2022年12月17日 2.4k阅读 2评论 4点赞

1.二进制和八进制表示法

  • ES6提供二进制和八进制的新写法:

    • 二进制:0b(或0B);
    • 八进制:0o(或0O);
// 二进制:0b/0B
let res1 = (0b111110111 === 503); 
console.log(res1); // true

// 八进制:0o/0O
let res2 = (0o767 === 503);
console.log(res2); // true
  • ES5开始,==严格模式下八进制数不允许使用前缀0表示==;
// 严格模式下,不允许使用0前缀表示八进制数,需要用0o形式的前缀
// 非严格模式
(function () {
    console.log(0o11 === 011); // true
})()

// 严格模式下
(function () {
    "use strict"
    console.log(0o11 === 011); // Octal literals are not allowed in strict mode.
})()
  • 转换为十进制数:使用Number()方法;
// 转换为十进制数:使用number()方法
console.log(Number(0b111)); // 7
console.log(Number(0o111)); // 73
console.log(Number(0x111)); // 23

2.Number.isFinite()、Number.isNaN()

  • Number.isFinite():用于检查一个数值是否为有限的;
Number.isFinite(1); // true
  • ES5中可以用下列代码部署该方法:
// ES5中部署Number.isFinite()方法的代码
(function (global) {
    // 这里没太看懂
    var global_isFinite = global.isFinite;
    // 自定义Number对象的isFinite属性
    Object.defineProperty(Number,'isFinite',{
        value : function (value) {
            return typeof value === 'number' && global_isFinite(value);
        },
        configurable : true,
        enumerable :false,
        writable : true
    })
})(this);
  • Number.isNaN():用来检查一个值是否为NaN;
  • 非NaN数值一律返回false;
Number.isNaN(NaN); // true
  • ES5中可以用下列代码部署该方法:
// ES5中部署Number.isNaN()方法的代码
(function (global) {
    // 这里没太看懂
    var global_isNaN = global.isNaN;
    // 自定义Number对象的isFinite属性
    Object.defineProperty(Number,'isNaN',{
        value : function (value) {
            return typeof value === 'number' && global_isNaN(value);
        },
        configurable : true,
        enumerable :false,
        writable : true
    })
})(this);

3.parseInt()和parseFloat()方法

  • ES6将这两个方法移植到了Number对象上面,行为与原先保持一致;
  • 这么做的==目的==是在于逐步减少全局性方法,使得JavaScript逐步模块化;
// ES6将这两个全局方法移植到了Number对象上
// ES5的写法
let res1 = parseInt("1.11"); // 1
let res2 = parseFloat("123.886#"); // 123.886

// ES6的写法
let res3 = Number.parseInt("1.111111"); // 1
let res4 = Number.parseFloat("12.12#@$"); // 12.12

4.Number.isInteger()方法

  • 作用:==判断一个值是否为整数==;
  • 在JavaScript内部,整数和浮点数是同样的存储方法,因此1和1.0被看做是同一个值;
  • ES5中部署该方法的代码见p88;
// 该方法用于判断一个数是否是整数
let res1 = Number.isInteger(12.0); // true
let res2 = Number.isInteger(12); // true

5.Number.EPSILON

  • ES6新增的一个==极小的常量==;
  • 引入该常量的==目的==:为浮点数计算设置一个误差范围;
  • 如果==误差小于这个常量==就可以==认为得到的是正确的浮点数运算结果==;
  • 该常量的实质其实是一个可以接受的误差范围;
// Number.EPSILON 一个常量  用于设置误差范围
const res1 = Number.EPSILON;
console.log(res1.toFixed(30)); // 0.000000000000000222044604925031

// 例子   误差检查函数
function withinErrorMargin(left,right){
    return Math.abs(right - left) < Number.EPSILON; // 计算结果与计算结果的目标值之差的绝对值与该常量
比较
}

console.log(withinErrorMargin(0.1 + 0.2 , 0.3)); // true
console.log(withinErrorMargin(0.1 + 0.3 , 0.3)); // false

6.安全整数和Number.isSafeInteger()

安全整数

  • JavaScript中能表示的整数范围在==正2的53次方到负2的53次方之间==,超出这个范围就无法精确表示;

Number.MAX_SAFE_INTEGER 和 Number.MIN_SAFE_INTEGER

  • 用于表示安全整数这个范围的上下限;
// Number.MAX_SAFE_INTEGER 和 Number.MIN_SAFE_INTEGER  表示安全整数范围的上下限
let res1 = Number.MAX_SAFE_INTEGER; // 9007199254740991
let res2 = Number.MIN_SAFE_INTEGER; // -9007199254740991

Number.isSafeInteger()方法

  • 用于检测一个整数是否在安全整数的范围内(处于安全范围内的整数返回true,其他数据类型以及范围外的数据都返回false);
// Number.isSafeInteger()  用于检测整数是否在安全整数的范围内
let res3 = Number.isSafeInteger(Number.MAX_SAFE_INTEGER); // true
let res4 = Number.isSafeInteger(Number.MAX_SAFE_INTEGER + 1); // false

Number.isSafeInteger()方法实现原理

  • 原理:仅需要将整数与范围边界作比较即可;
// Number.isSafeInteger()方法原理
function isSafeInteger(num) {
    return (typeof num === "number" && Math.round(num) === num && Number.MAX_SAFE_INTEGER >= num && 
Number.MIN_SAFE_INTEGER <= num);
}

console.log(isSafeInteger(1)); // true
console.log(isSafeInteger(Number.MAX_SAFE_INTEGER + 1)); // false
  • 在实际使用该方法时,不仅仅需要检测最后的运算结果是否在安全整数范围内,同时也需要检测所有参与运算的整数;
  • 检测两个运算数与结果的列子:
function trusty(left,right,result){
    /* 
    left:参与运算的第一个整数
    right:参与运算的第二个整数
    result:运算结果
    */
   if(Number.isSafeInteger(left) && Number.isSafeInteger(right) && Number.isSafeInteger(result)){
       return result;
   }
   throw new RangeError("某一数值不在安全范围内!");
}

console.log(trusty(1,2,3)); // 3

7.Math对象的扩展

  • ES6为Math新增了17个与数学相关的静态方法,只能在Math对象上调用;

Math.trunc()

  • 用于去除小数部分,返回一个整数;
  • 关于参数:

    • 非数值:先转换为Number类型;
    • 空值和无法截取整数的值:返回NaN;
// 1. Math.trunc() 去掉小数,返回一个整数
let res1 = Math.trunc(12.1212); // 12
let res2 = Math.trunc("123.321"); // 123  字符串先转换为Number
let res3 = Math.trunc(); // NaN
  • 对于未部署Math.trunc()方法的环境,可以使用以下代码模拟:
// 兼容不支持ES6语法的浏览器
Math.trunc = Math.trunc || function(x){
    // < 0 : 向上取整   > 0 向下取整
    return x < 0 ? Math.ceil(x) : Math.floor(x);
}

Math.sign()

  • 用于判断一个数是正数、负数、还是零;
  • 非数值会先转换为Number类型;
  • 返回值为以下有4种类型中的一个

    • 参数为正数:+1;
    • 参数为负数:-1;
    • 参数为0:0;
    • 参数为-0:0;
    • 参数为其他值:NaN;
// 2.Math.sign 方法:判断一个数是正数、负数、还是0
// 正数
let res4 = Math.sign(12); // 1
// 负数
let res5 = Math.sign(-12); // -1
// 0
let res6 = Math.sign(0); // 0
// -0
let res7 = Math.sign(-0); // 0
// NaN
let res8 = Math.sign(NaN); // NaN
  • 对于未部署ES6的环境,可以用以下方法模拟:
// ES5语法模拟Math.sign()方法
Math.sign = Math.sign || function (x) {
    x = +x; // 转换为数值
    if(x === 0 || Math.isNaN(X)){
        return x;
    }
    return x > 0 ? 1 : -1;
}

Math.cbrt()

  • 该方法用于计算一个数的立方根;
// Math.cbrt() 计算立方根
let re1 = Math.cbrt(8); // 2
let re2 = Math.cbrt("test"); //NaN
  • 对于未实现ES6语法的环境,可用以下方法来模拟:
// ES5模拟Math.cbrt()方法
Math.cbrt = Math.cbrt || function (x) {
    return Math.pow(Math.abs(x),1/3);  // Math.pow(a,b):返回a的b次幂结果
}

Math.clz32()

  • 将参数转为 32 位无符号整数的形式,然后返回这个 32 位值里面有多少个前导 0;
// 4.Math.clz32()  将参数转换为32位二进制,并返回前补0的个数
let re3 = Math.clz32(1); // 31
  • 对于小数,Math.clz32()只考虑整数部分;
// 对于小数  只考虑整数部分
let re4 = Math.clz32(1.22); // 31
  • 左移运算符与Math.clz32()方法直接相关(左移运算能改变前补0的个数):
// 左移运算符与该方法的关系
let re5 = Math.clz32(1 << 1); // 30
  • 空值和其他类型:先转换为Number类型;

Math.imul()

  • 作用:返回两个数以32位带符号整数形式相乘的结果,返回的结果也是带符号的32位整数形式;
  • 该方法等同于a*b的形式,但是为什么还需要Math.imul()方法

    • 因为JavaScript有精度限制,超过正负2的53次方的数值就无法精确表示,因此对于很大位数的乘法,其低位数值往往都是不准确的;
    • ==使用Math.imul()方法可以返回正确的低位数值==;
// Math.imul() 求两个数32位无符号整数形式之积  并返回32位无符号整数形式的结果
let re1 = Math.imul(0x7fffffff, 0x7fffffff); // 1

Math.fround()

  • 作用:返回一个数的单精度浮点数形式;

Math.hypot()

  • 返回所有参数的平方和的平方根;

对数方法

Math.expm1()

  • Math.expm1(x)返回 ex - 1,即Math.exp(x) - 1;

Math.log1p()

  • Math.log1p(x)方法返回1 + x的自然对数,即Math.log(1 + x)。如果x小于-1,返回NaN。

Math.log10()

  • Math.log10(x)返回以 10 为底的x的对数。如果x小于 0,则返回 NaN;

Math.log2()

  • Math.log2(x)返回以 2 为底的x的对数。如果x小于 0,则返回 NaN。

双曲函数方法

  • Math.sinh(x) 返回x的双曲正弦(hyperbolic sine)
  • Math.cosh(x) 返回x的双曲余弦(hyperbolic cosine)
  • Math.tanh(x) 返回x的双曲正切(hyperbolic tangent)
  • Math.asinh(x) 返回x的反双曲正弦(inverse hyperbolic sine)
  • Math.acosh(x) 返回x的反双曲余弦(inverse hyperbolic cosine)
  • Math.atanh(x) 返回x的反双曲正切(inverse hyperbolic tangent)

8.指数运算符

  • 写法:**
  • a**b:表示a的b次方;
a **= a;//等于 a=a*a

a ***= a;//等于 a=a*a*a

10.BigInt数据类型

  • JavaScript 所有数字都保存成 64 位浮点数,这给数值的表示带来了两大限制。一是数值的精度只能到53个二进制位(相当于16个十进制位),大于这个范围的整数,JavaScript是无法精确表示的,这使得JavaScript不适合进行科学和金融方面的精确计算。二是大于或等于2的1024次方的数值,JavaScript 无法表示,会返回Infinity。
  • 用来表示整数,没有位数的限制,任何位数的整数都能精确表示
// BigInt  用来表示整数,没有位数限制,因此能精确表示任何位数
const a = 2172141653n;
const b = 15346349309n;

// BigInt 可以保持精度
a * b // 33334444555566667777n

// 普通整数无法保持精度
Number(a) * Number(b) // 33334444555566670000
  • 为了与Number类型区分,==BigInt类型需要加后缀n==;
// BigInt类型需要加后缀n
// 普通数字
1n + 2n; // 3n

// 各种进制表示
0b1101n // 二进制
0o777n // 八进制
0xFFn // 十六进制
  • BigInt类型与普通整数是两种值,两者并不相等;
// BigInt类型与普通整数是两种值,两者并不相等
(1n === 1); // false
  • typeof对BingInt返回bigint;
// typeof对BingInt返回bigint
(typeof 1n); // bigint
  • BinInt可以使用-号,但是不可以使用+号,会与asm.js冲突;
-42n // 正确
+42n // 报错

BigInt对象

  • JavaScript 原生提供BigInt对象,可以用作构造函数生成 BigInt 类型的数值。转换规则基本与Number()一致,将其他类型的值转为 BigInt;
BigInt(123);// 123n
BigInt("123"); // 123n
BigInt(true); // 1n
BigInt(false); // 0n
  • BigInt构造函数在使用时,必须有参数,且参数必须要可以转换为数值,否则会报错(如null、undefined等);
  • 参数不可以是小数;

BigInt提供的方法

  • 继承了Object对象的两个方法:

    • BigInt.prototype.toString()
    • BigInt.prototype.valueOf()
  • 继承了Number对象的一个实例方法:

    • BigInt.prototype.toLocaleString()
  • 自身提供三个静态方法:

    • BigInt.asUintN(width, BigInt): 给定的 BigInt 转为 0 到 2width - 1 之间对应的值。
    • BigInt.asIntN(width, BigInt):给定的 BigInt 转为 -2width - 1 到 2width - 1 - 1 之间对应的值。
    • BigInt.parseInt(string[, radix]):近似于Number.parseInt(),将一个字符串转换成指定进制的 BigInt。
  • 转换规则:可以使用Boolean()、Number()和String()这三个方法,将 BigInt 可以转为布尔值、数值和字符串类型。
  • 数学运算:

    • 除了不带运算符的右移位运算符(>>>)和一元求和运算符(+),其他的都可以用;
    • 不能与普通数值混合运算;
4

—— 评论区 ——

昵称
邮箱
网址
取消
  1. @
    头像
    卢本伟
    Windows 10 x64 Edition   Google Chrome 108

    表情

  2. @
    头像
    JavaScript大王 博主
    Windows 10 x64 Edition   Google Chrome 108

    表情

博主栏壁纸
14 文章数
18 标签数
10 评论量
人生倒计时
舔狗日记