全栈之路——前端(一):ES6之数值、运算符的扩展

本文为电子书《ECMAScript 6 入门》:ES6入门教程学习笔记

数值的扩展

1. 二进制和八进制表示

引入了前缀0b和0o

0b111110111 === 503 //true
0o767 === 503 //true

二进制和八进制转为十进制要使用Number()方法。

2. 数值分隔符

ES2021允许使用下划线_作为分隔符,注意点如下
不能放在数值的最前面(leading)或最后面(trailing)。
不能两个或两个以上的分隔符连在一起。
小数点的前后不能有分隔符。
科学计数法里面,表示指数的e或E前后不能有分隔符。

3. Number的新方法

3.1 Number.isFinite()

用来判断数字是否有限,同时如果参数不是数值类型则返回false,而全局方法isFinite()会先将非数值的值转化为数值再进行判断。

Number.isFinite(15); // true
Number.isFinite(0.8); // true
Number.isFinite(NaN); // false
Number.isFinite(Infinity); // false
Number.isFinite(-Infinity); // false
Number.isFinite('foo'); // false
Number.isFinite('15'); // false
Number.isFinite(true); // false

isFinite(25) // true
isFinite("25") // true
3.2 Number.isNaN()

用来检测数字是否为NaN,同上,如果参数类型不是数值返回false,全局方法isNaN会进行转化。

Number.isNaN(NaN) // true
Number.isNaN(15) // false
Number.isNaN('15') // false
Number.isNaN(true) // false
Number.isNaN(9/NaN) // true
Number.isNaN('true' / 0) // true
Number.isNaN('true' / 'true') // true

isNaN(NaN) // true
isNaN("NaN") // true
3.3 Number.parseInt()

全局方法parseInt()移植而来,行为不变。

3.4 Number.parseFloat()

全局方法parseFloat()移植而来,行为不变。

3.5 Number.isInteger()

具体规则见代码

Number.isInteger(25) // true
Number.isInteger(25.1) // false
Number.isInteger(25.0) // true
Number.isInteger() // false
Number.isInteger(null) // false
Number.isInteger('25') // false
Number.isInteger(true) // false

JS中数值存储为64位双精度格式,数值精度最多可以达到53个二进制位,第54位及以后的位会被丢弃,导致误判:

Number.isInteger(3.0000000000000002) // true
3.6 Number.EPSILON

表示JS的最小精度,相当于2的-52次方,主要是为了给浮点数计算设置一个误差范围,比如,误差范围设为 2 的-50 次方(即Number.EPSILON * Math.pow(2, 2)),即如果两个浮点数的差小于这个值,我们就认为这两个浮点数相等

function withinErrorMargin (left, right) {
  return Math.abs(left - right) < Number.EPSILON * Math.pow(2, 2);
}

0.1 + 0.2 === 0.3 // false
withinErrorMargin(0.1 + 0.2, 0.3) // true

1.1 + 1.3 === 2.4 // false
withinErrorMargin(1.1 + 1.3, 2.4) // true
3.7Number.isSafeInteger()

JavaScript 能够准确表示的整数范围在-253到253之间(不含两个端点),超过这个范围,无法精确表示这个值。ES6 引入了Number.MAX_SAFE_INTEGER和Number.MIN_SAFE_INTEGER这两个常量,用来表示这个范围的上下限。Number.isSafeInteger()则是用来判断一个整数是否落在这个范围之内。

4. Math的新方法

4.1 Math.trunc()

用于去除一个数的小数部分,返回整数部分,并将非数值转化为数值,其余不符合条件的返回NaN。

Math.trunc(4.1) // 4
Math.trunc(4.9) // 4
Math.trunc(-4.1) // -4
Math.trunc(-4.9) // -4
Math.trunc(-0.1234) // -0

Math.trunc('123.456') // 123
Math.trunc(true) //1
Math.trunc(false) // 0
Math.trunc(null) // 0

Math.trunc(NaN);      // NaN
Math.trunc('foo');    // NaN
Math.trunc();         // NaN
Math.trunc(undefined) // NaN

null转化成数值类型竟然是0。

4.2 Math.sign()

用来判断一个数是整数负数或0

Math.sign(-5) // -1
Math.sign(5) // +1
Math.sign(0) // +0
Math.sign(-0) // -0
Math.sign(NaN) // NaN

Math.sign('')  // 0
Math.sign(true)  // +1
Math.sign(false)  // 0
Math.sign(null)  // 0
Math.sign('9')  // +1
Math.sign('foo')  // NaN
Math.sign()  // NaN
Math.sign(undefined)  // NaN
4.3 Math.cbrt()

用来计算一个数的立方根

4.4 Math.imul()

返回两个数以32位带符号整数相乘的结果,比*运算符的精度更高

4.5 Math.fround()

返回一个数的单精度浮点数形式,主要用于将64位双精度浮点数转化为32位单精度浮点数,如果小数的精度超过24个二进制位,返回值就会不同于原值,否则返回值不变

4.6 Math.hypot()

返回所有参数的平方和的平方根。

4.7 对数

Math.expm1(x)返回 ex - 1,即Math.exp(x) - 1。
Math.log1p(x)方法返回1 + x的自然对数,即Math.log(1 + x)。如果x小于-1,返回NaN。
Math.log10(x)返回以 10 为底的x的对数。如果x小于 0,则返回 NaN。
Math.log2(x)返回以 2 为底的x的对数。如果x小于 0,则返回 NaN。

5. BigInt

JS中所有数字都是64位双精度浮点数,进而导致数值的精度只能精确到53个二进制位,及16个十进制位,大于这个范围的整数无法精确表示,大于或等于2的1024次方的数也会无法表示,返回Infinity。BigInt就是用来解决这个问题的,为了与Number区分,数字后加n。并原生提供BigInt函数。

运算符的扩展

1. 指数运算符

这个运算符的一个特点是右结合,而不是常见的左结合。多个指数运算符连用时,是从最右边开始计算的。指数运算符可以与等号结合,形成一个新的赋值运算符(**=)。

// 相当于 2 ** (3 ** 2)
2 ** 3 ** 2
// 512
let a = 1.5;
a **= 2;
// 等同于 a = a * a;
let b = 4;
b **= 3;
// 等同于 b = b * b * b;

2. 链判断运算符

在对对象进行多层的属性获取时,其实正确的写法是对每一层都进行一次空判:

// 错误的写法
const  firstName = message.body.user.firstName || 'default';

// 正确的写法
const firstName = (message
  && message.body
  && message.body.user
  && message.body.user.firstName) || 'default';

为了避免这种复杂的写法,ES2020引入了链判断运算符?.:

const firstName = message?.body?.user?.firstName || 'default';
const fooValue = myForm.querySelector('input[name=foo]')?.value

有三种写法。
obj?.prop // 对象属性是否存在
obj?.[expr] // 同上
func?.(…args) // 函数或对象方法是否存在

3. Null判断运算符

Null判断运算符类似||,但是||会将null和undefined与空字符串/false/0混淆,因此推出??运算符,主要使用场景是给空值设置默认值

4. 逻辑赋值运算符

// 或赋值运算符
x ||= y
// 等同于
x || (x = y)

// 与赋值运算符
x &&= y
// 等同于
x && (x = y)

// Null 赋值运算符
x ??= y
// 等同于
x ?? (x = y)

5. #!命令

ES2023 为 JavaScript 脚本引入了#!命令,写在脚本文件或者模块文件的第一行。

// 写在脚本文件第一行
#!/usr/bin/env node
'use strict';
console.log(1);

// 写在模块文件第一行
#!/usr/bin/env node
export {};
console.log(1);

有了这一行以后,Unix 命令行就可以直接执行脚本。

# 以前执行脚本的方式
$ node hello.js

# hashbang 的方式
$ ./hello.js
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值