JavaScript 可选链操做符&&空值合并操做符

背景

最近 开始接触到一些ES6之后的新特性 使用起来确实方便了很多markdown

尤为是最近有一个项目 在方法中须要传入index 可是在作非空验证的时候 若是传入的index是0 也会被判断为false 这就十分头疼了app

冗余的判断不只使代码的可读性变差 并且会使代码变得不简洁ide

可是在接触到可选链操做符后 emmmmm 这也太香了 避免了 && 和 多余的非空校验函数

因此决定以此为开始 陆续的写一些ES6 ES7...以后的新特性ui

可选链操做符

初识

这里我引用一段MDN上的解释lua

可选链操做符( ?. )容许读取位于链接对象链深处的属性的值,而没必要明确验证链中的每一个引用是否有效。?. 操做符的功能相似于 . 链式操做符,不一样之处在于,在引用为空(nullish ) (null 或者 undefined) 的状况下不会引发错误,该表达式短路返回值是 undefined。与函数调用一块儿使用时,若是给定的函数不存在,则返回 undefined。url

或许 你仍是?????spa

不要急 咱们来看一道例题3d

const adventurer = {
  name: '林克',
  weapon: {
    name: '大师剑'
  }
};

const weaponName = adventurer.weapon?.name;
console.log(weaponName);
// expected output: 大师剑

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

const shieldName = adventurer.shield?.name;
console.log(shieldName);
// expected output: undefined
复制代码

上述例子adventurer.weapon?.namecode

咱们试图去寻找adventurer对象下的weapon属性下的name属性

adventurer对象有weapon属性 因此返回咱们能够取出咱们的大师剑

而后是adventurer.savePrincess?.()

显然adventurer下没有savePrincess这个方法 因此救公主??? 不存在的 直接返回undefined

最后是adventurer.shield?.name

一样的 咱们发现 adventurer对象下也没有shield属性 因此直接返回undefined

好啦 至此 咱们大概理解了可选链是怎么一回事

接下来 咱们来看看 可选链有什么须要注意的地方

注意点

可选链不能用于赋值

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

短路计算

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

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

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

最后再举一个本身在实际开发中的例子

假若有一个方法setStudentResult(action) 它接收一个对象action

为了让咱们的代码健壮 咱们必须在方法内部作出参数的非空校验 显然下面这样是不行的

const list = {};

/** * @param {*} action */
function setStudent (action) {
  list[action.index] = action.student;
}
复制代码

若是咱们直接调用setStudent() 显然整个程序都会崩溃

因此在之前 咱们能够将方法体改为这样

// 同时包含函数接收了action参数 而且参数中有咱们须要的内容
function setStudent(action) {
  if (action) {
    if (action.index && action.student) {
      list[action.index] = action.student;
    }
  }
}
复制代码

可是 若是使用可选链操做符 咱们就能够将方法定义成以下

function setStudent (action) {
  if (action?.index && action?.student) {
    list[action.index] = action.student;
  }
}
复制代码

能够看到 不管是可读性 仍是简洁程度 可选链操做符都更胜一筹

空值合并操做符

仍是引用一段MDN上解释

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

对比 ||

咱们知道 || 逻辑或运算符 也具备类似的功能

也就是在 || 左侧操做数为假值时 会返回右侧 操做数

JS中的假值有

  • 0

  • ''

  • NaN

  • null

  • undefined

因此设想一个场景 咱们对一个function中的参数使用 || 运算符 来判断用户是否输入

function addNum(a,b) {
  var a = a || 0
  var b = b || 0
  return a + b 
}
复制代码

上述代码咱们用 || 运算符来判断用户 用户输入的合法性

可是这样咱们就没法排除 0 这种状况

若是用户就是输入了0 可是0依旧是一个假值 因此仍是会返回 || 操做符右侧是操做数

这就与咱们的预期不一致了

而 ?? 空值合并操做符就只是检验了 null 和 undefined

注意点

短路计算

与 OR 和 AND 逻辑操做符类似,当左表达式不为 null 或 undefined 时,不会对右表达式进行求值

var a = 1;
undefined ?? a++;
console.log(a); // 1

var b = 1;
true ?? b++;
console.log(b); // 2
复制代码

不能与 AND 或 OR 操做符共用

null || undefined ?? "foo"; // 抛出 SyntaxError
true || undefined ?? "foo"; // 抛出 SyntaxError
复制代码

与可选链操做符连用

两个操做符都是针对 undefined 和 null 两个值

因此咱们能够结合这两个操做符

let customer = {
  name: "chou",
  details: { age: 100 }
};
let customerCity = customer?.city ?? "荒野之息";
console.log(customerCity); // 荒野之息
复制代码
相关文章
相关标签/搜索