全部 / 前端 / 技术 · 2022年6月5日 0

31 – 可选链

广告位招租 (vx: ghostcode, 备注:网站广告)

原文地址:https://dev.to/bhagatparwinder/optional-chaining-1a1f

简介

JavaScript 中获取对象属性是一个常见操作,多数时候这些属性是嵌套的。当你从一个不存在的对象上获取属性的时候,JavaScript 就会报错。

让我们来举一些例子来帮助理解:

const myObject = {
    name: "Parwinder",
    car: "Cybertruck",
    age: 42,
    computers: {
        first: {
            name: "iMac",
            year: 2017,
            spec: {
                cpu: "i7",
                ram: "16GB"
            }
        },
        second: {
            name: "MacBook Pro"
        }
    }
}

console.log(myObject.computers.first.spec.cpu); // i7
console.log(myObject.computers.second.spec.cpu); // Cannot read property 'cpu' of undefined

第一条日志通过巡查对象来获取我第一台电脑上的 CPU,当同样的方法用在第二台电脑上时就报错。

当 spec 不存在时我们依旧在尝试获取 spec 上的 cpu,cpu 在对象的第五层它前面的任何一层都有可能为 null 或 undefined。

我们通过 if 语句配合 && 操作符来解决此问题:

if(myObject && myObject.computers && myObject.computers.second && myObject.computers.second.spec) {
    console.log(myObject.computers.second.spec.cpu);
}

及时上面的脚本可以正确运行,但代码不够整洁。有太多的代码来校验 null / undefined 。

可选链通过 ?. 来表示,它可以用于对象上的键和表达式、数组索引以及对象上的函数。

对象的属性应用可选链

我们可以使用可选链来重写上面的 if 语句:

myObject?.computers?.second?.spec?.cpu // undefined

// Concise and easy to read code
// or

myObject.computers.second.spec?.cpu

?. 操作符可以把对象上的属性进行短路求值。可选链不是通过继续求值来返回错误,而是一旦发现链中的第一个 undefined 或 null,就立即终止,并返回 undefined。

?. 只在它使用的地方起作用。

myObject.computers.second.spec?.cpu 中的前三个属性都必须存在,这里只有 spec 引用了可选链,若 spec 不存在才返回 undefined

前面三个任何一个属性缺失都会报错,所以只在属性可能存在或不存在的地方使用?.。若代码中各处使用会导致静默失败而且很难定位调试。

例如:若 computers 是可选的,但是 myObject 是一定会存在的,那应该写成下面:

myObject.computers?.

而不是:

myObject?.computers?.

对象的表达式应用可选链

我们在通过字面量或中括号来获取对象属性时依旧可以使用可选链。

console.log(myObject.computers.second?.["spec"].cpu); // undefined
console.log(myObject.computers.first?.["spec"].cpu); // i7

对象的函数应用可选链

我们在对象上添加一个函数:

const myObject = {
    name: "Parwinder",
    car: "Cybertruck",
    age: 42,
    getAge: function () {
        return this.age;
    }
}

console.log(myObject.getAge()); // 42

如果函数是可选的,我们可以加入可选链。

console.log(myObject.getAge?.());

可选链会确保 JavaScript 视图执行一个不存在的函数,但由于 ?. 提供的短路操作实际上调用永远不会发生。

对象上的数组应用可选链

const names = ["Parwinder", "Lauren", "Leah", "Robert", "Eliu"];
console.log(names[3]); // Robert

const newEmployee = names?.[3]; // Check if names exists
console.log(newEmployee); // Robert

注意:可选链不能应用在赋值的左侧。

let myObject = {};
myObject?.name = "Parwinder"; // Uncaught SyntaxError

前端黑板报