字符串
实例对象新增方法
- ES5中,字符串的实例方法
replace()
只能替换第一个匹配。- 如:
'aabbcc'.replace('b', '_') // 'aa_bcc'
- 如果想全部匹配,需要用正则
'aabbcc'.replace(/b/g, '_') // 'aa__cc'
- 如:
- ES11,推出新方法
replaceAll()
,可以一次性替换所有匹配
数值
数值的扩展
BigInt数据类型
- ES5 所有数字都保存成 64 位浮点数,这给数值的表示带来了两大限制
- 一是,数值的精度只能到 53 个二进制位(相当于 16 个十进制位),大于这个范围的整数,JS 是无法精确表示。这使得 JS 不适合进行科学和金融方面的精确计算
- 二是大于或等于2的1024次方的数值,JS 无法表示,会返回
Infinity
- ES11引入数据类型:
BigInt
(大整数),来解决这个问题- 这是 ES 的第八种数据类型
BigInt
只用来表示整数,没有位数的限制,任何位数的整数都可以精确表示BigInt
类型的数据必须添加后缀n
BigInt
同样可以使用各种进制表示,都要加上后缀nBigInt
与普通整数是两种值,它们之间并不相等。typeof 12n === bigint
BigInt
可以使用负号(-),但是不能使用正号(+) ```javascript 1234 // 普通整数 1234n // BigInt
// BigInt 的运算 1n + 2n // 3n
const a = 2172141653n; const b = 15346349309n;
// BigInt 可以保持精度 a * b // 33334444555566667777n
// 普通整数无法保持精度 Number(a) * Number(b) // 33334444555566670000
0b1101n // 二进制 0o777n // 八进制 0xFFn // 十六进制
42n === 42 // false
```javascript
// 计算70!,即70的阶乘
let p = 1n;
for (let i = 1n; i <= 70n; i++) {
p *= i;
}
console.log(p); // 11978571...00000000n
BigInt
的数学运算为何出现:读取对象内部的某个属性,往往需要判断一下,属性的上层对象是否存在 ```javascript // 可能报错的写法 // 如果message、body、user任何一个为undefined,都将报错 const firstName = message.body.user.firstName || ‘default’;
// 正确的写法 // 需要判断四次,每一层是否有值。很麻烦 const firstName = (message && message.body && message.body.user && message.body.user.firstName) || ‘default’;
- 链判断运算符`?.`的引入,简化了上面的写法
- `?.`运算符,直接在链式调用的时候判断,左侧的对象是否为`null`或`undefined`。如果是的,就不再往下运算,而是返回`undefined`
```javascript
const firstName = message?.body?.user?.firstName || 'default';
- 链判断运算符
?.
的三种写法obj?.prop
:对象属性是否存在obj?.[prop]
:对象属性是否存在obj?.func()
:对象方法是否存在func?.()
:函数是否存在 ```javascript // 案例一 a?.b // 等同于 a == null ? undefined : a.b
a?.[x] // 等同于 a == null ? undefined : a[x]
a?.b() // 等同于 a == null ? undefined : a.b()
a?.() // 等同于 a == null ? undefined : a()
```javascript
// 案例二:会报错的情况
// 构造函数
new a?.()
new a?.b()
// 链判断运算符的右侧有模板字符串
a?.`{b}`
a?.b`{c}`
// 链判断运算符的左侧是 super
super?.()
super?.foo
// 链运算符用于赋值运算符左侧
a?.b = c
Null判断运算符??
- Null 判断运算符
??
- 它的行为类似
||
,但是只有运算符左侧的值为null
或undefined
时,才会返回右侧的值 - 用了
??
,如果多个逻辑运算符一起使用,必须用括号表明优先级,否则会报错 ```javascript // 案例一:|| 和 ?? 的区别 false || 55; // 55 0 || 55; // 55
- 它的行为类似
false ?? 55; // false 0 ?? 55; // 0
```javascript
// 案例二
null ?? 55; // 55
undefined ?? 55; // 55
// 案例三:因为优先级的报错
lhs && middle ?? rhs
lhs ?? middle && rhs
lhs || middle ?? rhs
lhs ?? middle || rhs