一、 短路运算
短路运算是一种常见的逻辑运算方式,其核心机制是在运算过程中进行一些优化和简化,从而提高计算效率和减少资源消耗。特别是在处理逻辑与(&&)和逻辑或(||)运算时,如果左侧的表达式已经能够确定整个逻辑表达式的结果,那么右侧的表达式将不会被执行,因此任何与其求值产生的相关副作用都不会生效。
二、 逻辑赋值运算符
- &&=:逻辑与赋值运算符 x &&= y 等价于 x && (x=y):意思是当 x 为真时,x = y。
- ||=:逻辑或赋值运算符 x ||= y 等价于 x || (x = y):意思是仅在 x 为 false 的时候,x = y。
- ??=:逻辑空赋值运算符 x ??= y 等价于 x ?? (x = y):意思是仅在
x 为 null 或 undefined
的时候,x = y
//&&=
let a = 1;
a &&= 2;
console.log(a); // 2
//||=
const aa = { duration: 50, title: '' };
aa.duration ||= 10;
console.log(aa.duration); // 50
aa.title ||= 'title is empty.';
console.log(aa.title); // "title is empty"
//??=
const a = { duration: 50 };
ac.duration ??= 10;
console.log(ac.duration); // 50
ac.speed ??= 25;
console.log(ac.speed); // 25
常见应用
- 用于条件判断、链式判断以及空指针判断等场景。例如,在判断一个对象是否为空以及其属性是否满足特定条件时,可以使用短路运算来避免空指针异常。
- 进行复杂的条件判断时,如果某个关键条件不满足(即为假),则后续的条件判断可以省略,从而提高代码执行效率。
使用示例
在日常开发中,像以现一些代码是可以用逻辑赋值运算符代替
// 给data.code为空时,赋值为y
// 示例1
if (!data.code) {
data.code= y
}
// 示例2
data.code? "" : (data.code = y)
可以使用逻辑与替代
data.code ||= y
三、其他常用运算符
1. 空值合并运算符(??)
空值合并运算符(??)是一个逻辑运算符,当左侧的操作数为 null 或者 undefined 时,返回其右侧操作数,否则返回左侧操作数。
与逻辑或运算符(||)不同,逻辑或运算符会在左侧操作数为假值时返回右侧操作数。也就是说,如果使用 || 来为某些变量设置默认值,可能会遇到意料之外的行为。比如为假值(例如,‘’ 或 0)时。见下面的例子。
const foo = null ?? 'default string';
console.log(foo);
// Expected output: "default string"const baz = 0 ?? 42;
console.log(baz);
// Expected output: 0
为变量赋默认值
由于 || 是一个布尔逻辑运算符,左侧的操作数会被强制转换成布尔值用于求值。任何假值(0, ‘’, NaN, null, undefined)都不会被返回。这导致如果你使用0,''或NaN作为有效值,就会出现不可预料的后果。
let count = 0;
let text = "";
let qty = count || 42;
let message = text || "hi!";
console.log(qty); // 42,而不是 0
console.log(message); // "hi!",而不是 ""// An empty string (which is also a falsy value)
let myText = "";
let notFalsyText = myText || "Hello world";
console.log(notFalsyText); // Hello world
let preservingFalsy = myText ?? "Hi neighborhood";
console.log(preservingFalsy); // '' (as myText is neither undefined nor null)
2. 可选链运算符(?.)
可选链运算符(?.)允许读取位于连接对象链深处的属性的值,而不必明确验证链中的每个引用是否有效。
?. 运算符的功能类似于 . 链式运算符,不同之处在于,在引用为空 (nullish ) (null 或者 undefined) 的情况下不会引起错误,该表达式短路返回值是 undefined。
let potentiallyNullObj = null;
let x = 0;
let prop = potentiallyNullObj?.[x++];
console.log(x); // x 将不会被递增,依旧输出 0
可以结合空值合并运算符设置默认值
空值合并运算符针对 undefined 与 null 这两个值,可选链式运算符(?.) 也是如此。在访问属性可能为 undefined 与 null 的对象时,?.与??结合使用非常有用。
let customer = {name: "Carl",details: { age: 82 },
};
let customerCity = customer?.city ?? "暗之城";
console.log(customerCity); // “暗之城”
可选链不能用于赋值
需要注意的是时,可选链是不用用于赋值对象的
let object = {};
object?.property = 1; // Uncaught SyntaxError: Invalid left-hand side in assignment
3、TypeScript中的非空断言操作符(!)
由于可选链不能用于赋值,所以在没有属性接口或类型定义的情况下,如何给没有明确属性定义的对象赋值呢?
let object=await getObject();
object!.code='A001'
!
是TypeScript中的非空断言操作符。它告诉TypeScript编译器,尽管从静态类型检查的角度来看,code 属性可能是 null 或 undefined,但在实际运行时,你确信它不是。这通常是因为你确信在某个特定的代码执行路径中,该属性已经被正确地初始化了。
使用非空断言操作符需要谨慎,因为它可能会掩盖潜在的错误。如果你断言了一个实际上可能是 null 或 undefined 的值,那么在运行时可能会出现错误。为了避免这种情况,你可能需要在赋值之前添加一些额外的检查。