可选链操作符的使用

官网定义:

        可选链操作符( ?. )允许读取位于连接对象链深处的属性的值,而不必明确验证链中的每个引用是否有效。?. 操作符的功能类似于 . 链式操作符,不同之处在于,在引用为空(nullish ) (null 或者 undefined) 的情况下不会引起错误,该表达式短路返回值是 undefined。与函数调用一起使用时,如果给定的函数不存在,则返回 undefined

优点:当尝试访问可能不存在的对象属性时,可选链操作符将会使表达式更短、更简明。在探索一个对象的内容时,如果不能确定哪些属性必定存在,可选链操作符也是很有帮助的

我的理解就是简化的三元判断,首先隐式的判断?前的变量是否存在,( 既不是 null 也不是 undefined。)如果是null或者undefind 表达式将会短路计算直接返回 undefined

// 正常写法:为了避免报错,在访问obj.first.second之前,要保证 obj.first 的值既不是 null,
//也不是 //undefined。如果只是直接访问 obj.first.second,而不对 obj.first 进行校验,则有可能抛出
//错误。

let nestedProp = obj.first && obj.first.second;

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


let nestedProp = obj.first?.second

语法:

obj?.prop
obj?.[expr]
arr?.[index]
func?.(args)

可选链与函数调用

当尝试调用一个可能不存在的方法时也可以使用可选链。函数调用时如果被调用的方法不存在,使用可选链可以使表达式自动返回undefined而不是抛出一个异常。

注意:如果前不是一个方法名而是一个属性名,?.()是会报错的

let result = someInterface.customMethod?.();

 处理可选的回调函数或者事件处理器

例如 try...catch...

//  ES2019的写法
function doSomething(onContent, onError) {
  try {
    // ... do something with the data
  }
  catch (err) {
    if (onError) { // 校验onError是否真的存在
      onError(err.message);
    }
  }
}

// 使用可选链进行函数调用
function doSomething(onContent, onError) {
  try {
   // ... do something with the data
  }
  catch (err) {
    onError?.(err.message); // 如果onError是undefined也不会有异常
  }
}

可选链和表达式

        当使用【】来访问对象的属性时:

      let name = person?.['age'+'name']

可选链并不能用于赋值

let object = {};
object?.property = 1; 
// Uncaught SyntaxError: Invalid left-hand side in assignment

可选链访问数组元素

let arrayItem = arr?.[42];

 短路计算

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

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

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

可以连续使用可选链读取多层嵌套结构:

let customer = {
  name: "Carl",
  details: {
    age: 82,
    location: "Paradise Falls" // details 的 address 属性未有定义
  }
};
let customerCity = customer.details?.address?.city;

// … 可选链也可以和函数调用一起使用
let duration = vacations.trip?.getTime?.();

空值合并操作符

        空值合并操作符??)是一个逻辑操作符,当左侧的操作数为 null 或者 undefined 时,返回其右侧操作数,否则返回左侧操作数。

const foo = null ?? 'default string';
console.log(foo);
// expected output: "default string"

const baz = 0 ?? 42;
console.log(baz);
// expected output: 0

const nullValue = null;
const emptyText = ""; // 空字符串,是一个假值,Boolean("") === false
const someNumber = 42;

const valA = nullValue ?? "valA 的默认值";
const valB = emptyText ?? "valB 的默认值";
const valC = someNumber ?? 0;

console.log(valA); // "valA 的默认值"
console.log(valB); // ""(空字符串虽然是假值,但不是 null 或者 undefined)
console.log(valC); // 42

与或运算符的区别:

// “||”

let count = 0;
let text = "";

let qty = count || 42;
let message = text || "hi!";
console.log(qty);     // 42,而不是 0
console.log(message); // "hi!",而不是 ""
// “ ?? ”   只有??左边为null 或 undefind时,才会执行??右边的值

let count = 0;
let text = "";

let qty = count ?? 42;
let message = text ?? "hi!";
console.log(qty);     // 0
console.log(message); // ""

短路: 

function A() { console.log('函数 A 被调用了'); return undefined; }
function B() { console.log('函数 B 被调用了'); return false; }
function C() { console.log('函数 C 被调用了'); return "foo"; }

console.log( A() ?? C() );
// 依次打印 "函数 A 被调用了"、"函数 C 被调用了"、"foo"
// A() 返回了 undefined,所以操作符两边的表达式都被执行了

console.log( B() ?? C() );
// 依次打印 "函数 B 被调用了"、"false"
// B() 返回了 false(既不是 null 也不是 undefined)
// 所以右侧表达式没有被执行

*****  ?? 不能 直接与 AND(&&)和 OR(||)操作符组合使用

null || undefined ?? "foo"; // 抛出 SyntaxError
true || undefined ?? "foo"; // 抛出 SyntaxError

空值合并操作符针对 undefined 与 null 这两个值,可选链式操作符(?.) 也是如此。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值