神奇运算符:三元、可选链操作、非空赋值运算符

强大JavaScript运算符

1、多重三元运算(?:)

const size = val =>
  Array.isArray(val)
    ? val.length
    : val && typeof val === 'object'
    ? val.size || val.length || Object.keys(val).length
    : typeof val === 'string'
    ? new Blob([val]).size
    : 0;

size([1, 2, 3, 4, 5]); // 5
size('yuan'); // 4
size({ one: 1, two: 2, three: 3 }); // 3

这个的实现非常巧妙,利用 Blob 类文件对象的特性,获取对象的长度。

2、 非空运算符(??)

?? 运算符被称为非空运算符。
如果第一个参数不是 null/undefined,将返回第一个参数,否则返回第二个参数

null ?? 5
// 5
3 ?? 4
// 3

注意这里的假值只是 null/undefined

3、逻辑空赋值 (??=)

逻辑空赋值运算符 (x ??= y) 仅在 x 是 null 或 undefined时对其赋值。

const a = { duration: 50 };

a.duration ??= 10;
console.log(a.duration);
// expected output: 50

a.speed ??= 25;
console.log(a.speed);
// expected output: 25

??= 可用来初始化缺失的属性

const pages = [
  {
    title:'主要场景',
    path:'/'
  },
  {
    path:'/a'
  },
  {
    path:'/b'
  },
]

for (const page of pages){
    page.title ??= '默认标题'
}

console.table(pages)
//(index)   title          path
//0        "主要场景"       "/"
//1        "默认标题"       "/a"
//2        "默认标题"       "/b"

空赋值的短路用法
空值合并运算符从左至右求值

(结果非 null 或 undefined 的表达式) ?? expr 被短路求值为左侧表达式,当左侧证明为既非 null 也非 undefined.

语法短路意味着 expr 部分尚未被求值,因此任何与其求值产生的相关副作用都不会生效(例如,如果 expr 是一个函数调用,则该调用将不会发生)。

逻辑空赋值的语法短路也意味着 x ??= y 等价于:

x ?? (x = y);

而不等价于如下的表达式,因为其一定会发生赋值:

x = x ?? y;

在使用??=时,这里的假值只是 null/undefined

逻辑运算||=

在||=中判断的假值可以是''/null/undefined/0

const a = { duration: 50, title: '' };

a.duration ||= 10;
console.log(a.duration);
// expected output: 50

a.title ||= 'title is empty.';
console.log(a.title);
// expected output: "title is empty"

赋值表达式

a ||= b
//等价于
a = a || (a = b)

a &&= b
//等价于
a = a && (a = b)

a ??= b
//等价于
a = a ?? (a = b)

注意:

a ||= b:当a值不存在时,将b变量赋值给a
a &&= b:当a值存在时,将b变量赋值给a
a ??= b:当a值为null或者undefined时,将b变量赋值给a

4、可选链操作符(?.)

通过使用 ?. 操作符取代 . 操作符,JavaScript 会在尝试访问 obj.first.second 之前,先隐式地检查并确定 obj.first 既不是 null 也不是 undefined。如果obj.first 是 null 或者 undefined,表达式将会短路计算直接返回 undefined。

const adventurer = {
  name: 'Alice',
  cat: {
    name: 'Dinah'
  }
};

const dogName = adventurer.cat?.name;
console.log(dogName);
// expected output: Dinah

console.log(adventurer.cat?.age);
// expected output: undefined

如果在对象的每一层都需要判断

adventurer?.set?.age

在Map中使用可选链操作符

let myMap = new Map();
myMap.set("foo", {name: "baz", desc: "inga"});

let nameBar = myMap.get("bar")?.name;
console.log(nameBar)   // undefined

可选链操作符的短路计算

当在表达式中使用可选链时,如果左操作数是 null 或 undefined,表达式将不会被计算,例如:

let potentiallyNullObj = null;
let x = 0;
let prop = potentiallyNullObj?.[x++];

console.log(x); // x 将不会被递增,依旧输出 0

使用空值合并操作符

空值合并操作符可以在使用可选链时设置一个默认值:

let customer = {
  name: "Carl",
  details: { age: 82 }
};
let customerCity = customer?.city ?? "何小帅";
console.log(customerCity); // “何小帅”

你可能感兴趣的:(神奇运算符:三元、可选链操作、非空赋值运算符)