BigInt、展开运算符、解构和可选链运算符
1、BigInt
1.1、创建BigInt
可以使用以下两种方式来创建BigInt类型的值:
- 使用BigInt字面量
- 使用BigInt()函数
BigInt字面量的语法是在一个整数后面添加一个小写字母"n"。字母"n"必须紧随数字之后,两者之间不允许存在空白字符。示例如下:
ts
const unit = 1n;
使用BigInt()函数也能够创建BigInt类型的值。BigInt()函数会尝试将传入的参数转换为BigInt,最基本的使用场景是将一个整数转换为BigInt类型的值。示例如下:
ts
const unit = BigInt(1); // 1n
1.2、BigInt与Number
BigInt类型的值能够与Number类型的值进行大小及相等关系的比较。在进行严格相等比较时,BigInt类型的值与Number类型的值永远不相等。在进行非严格相等比较及大小关系比较时,BigInt类型的值与Number类型的值将进行数学意义上的比较。
虽然BigInt类型的值可以与Number类型的值进行比较,但是BigInt类型的值不允许与Number类型的值一起进行混合数学运算。示例如下:
ts
// 类型错误!无法混合使用BigInt和其他类型
let a = 1 + 1n;
通过内置的Number()函数能够将BigInt类型的值转换为Number类型的值。但要注意,在BigInt类型与Number类型之间进行强制类型转换时有可能损失精度。示例如下:
ts
Number(1n); //1
2、展开运算符
展开运算符是ECMAScript 2015中定义的运算符,可以用在多种上下文中,比如对象字面量、数组字面量和函数调用语句等。展开运算符使用连续的三个点符号"..."来表示。展开运算符的后面是一个表达式,表达式的求值结果为要展开的值。展开运算符的具体语法如下所示:
ts
...expression
2.1、展开数组字面量
在数组字面量中可以使用展开运算符。数组字面量中的展开运算符可以应用在任何可迭代对象上,它的作用是将迭代产生的每个值插入数组字面量的指定位置上。示例如下:
ts
const firstHalfYearSeasons = ['Spring', 'Summer'];
const seasons = [...firstHalfYearSeasons, 'Fall', 'Winter'];
console.log(seasons);//[ 'Spring', 'Summer', 'Fall', 'Winter' ]
数组字面量可以仅由一个展开元素构成,这相当于对数组进行了复制操作。
2.2、展开对象字面里
在对象字面量中也可以使用展开运算符。对象字面量中的展开运算符会将操作数的自身可枚举属性复制到当前对象字面量中。示例如下
ts
const point2d = {
x: 0,
y: 0,
};
const point3d = {
...point2d,
z: 0,
};
// { x: 0, y: 0, z: 0 }
console.log(point3d);
对象字面量可以仅由一个展开属性定义构成,这相当于对对象进行了复制操作。
4.2.3、展开函数参数
在调用一个函数时可以在实际参数列表中使用展开运算符来展开一个可迭代对象,它的作用是将迭代产生的每个值当成独立的实际参数传递给函数。示例如下:
js
const nums = [3, 1, 4];
const max = Math.max(...nums);
max; // 4
Math.max()是JavaScript的内置函数,它接受任意数量的数字参数并返回最大的数字。
3、解构
JavaScript中的解构是指将数组或对象在结构上进行分解,将其拆分成独立的子结构,然后可以访问那些拆分后的子结构。解构提供了一种更加便利的数据访问方式,使用解构语法能够极大地简化代码。
3.1、数组解构
数组解构赋值使用了类似于数组字面量的表示方式。赋值运算符右侧为需要解构的数组,赋值运算符左侧是解构赋值的目标,在解构赋值的同时也支持声明新的变量。下例中,将对point数组进行解构,然后把数组的第一个元素0赋值给变量x,第二个元素1赋值给变量y:
ts
const point = [0, 1];
const [x, y] = point;
x; // 0
y; // 1
3.2、对象解构
对象解构赋值使用了类似于对象字面量的表示方式。赋值运算符右侧为需要解构的对象,赋值运算符左侧是解构赋值的目标,在解构赋值的同时也支持声明新的变量。下例中,将对point对象进行解构,然后把属性x和y的值赋值给变量x和y:
ts
const point = { x: 0, y: 1 };
const { x, y } = point;
x; // 0
4、可选链运算符
可选链运算符是2019年12月纳入ECMAScript标准中的新特性。TypeScript 3.7版本增加了对可选链运算符的支持,因此我们可以在TypeScript 3.7及以上的版本中直接使用该运算符。
当尝试访问对象属性时,如果对象的值为undefined或null,那么属性访问将产生错误。为了提高程序的健壮性,在访问对象属性时通常需要检查对象是否已经初始化,只有当对象不为undefined和null时才去访问对象的属性。可选链运算符旨在帮助开发者省去冗长的undefined值和null值检查代码,增强了代码的表达能力。
4.1、基础语法
可选链运算符由一个问号和一个点号组成,即"?."。可选链运算符有以下三种语法形式:
- 可选的静态属性访问。
- 可选的计算属性访问。
- 可选的函数调用或方法调用。
1. 可选的静态属性访问:
ts
obj?.prop
在该语法中,如果obj的值为undefined或null,那么表达式的求值结果为undefined;否则,表达式的求值结果为obj.prop。
2. 可选的计算属性访问:
ts
obj?.[expr]
在该语法中,如果obj的值为undefined或null,那么表达式的求值结果为undefined;否则,表达式的求值结果为obj[expr]。
3. 可选的函数调用或方法调用
ts
fn?.()
在该语法中,如果fn的值为undefined或null,那么表达式的求值结果为undefined;否则,表达式的求值结果为fn()。
4.2、短路求值
如果可选链运算符左侧操作数的求值结果为undefined或null,那么右侧的操作数不会再被求值,我们将这种行为称作短路求值。在下例中,由于变量a的值为undefined,因此第4行中的变量x将不会执行自增运算:
ts
let x = 0;
let a = undefined;
a?.[++x]; // undefined
x; // 0
值得一提的是,二元逻辑运算符"&&"和"||"也具有短路求值的特性。
5、空值合并运算符
空值合并运算符在2019年11月成为ECMAScript标准中的候选特性。虽然还不是最终的标准,但核心功能已经基本确定。TypeScript 3.7版本增加了对空值合并运算符的支持,因此我们可以在TypeScript 3.7以上的版本中直接使用该运算符。
空值合并运算符是一个新的二元逻辑运算符,它使用两个问号"??"作为标识。空值合并运算符的语法如下所示:
ts
a ?? b
该语法中,当且仅当"??"运算符左侧操作数a的值为undefined或null时,返回右侧操作数b;否则,返回左侧操作数a。
空值合并运算符与可选链运算符一样都具有短路求值的特性。当空值合并运算符左侧操作数的值不为undefined和null时,右侧操作数不会被求值,而是直接返回左侧操作数。