在开发前端应用程序时,处理嵌套对象或数组的问题是一件普遍的事情。以前,可以使用条件语句或简单的逻辑检查来避免 options 检查或控制嵌套属性的访问。在 ECMAScript 2018(ES9)中,“Optional Chaining” 运算符就是一个新的特性,可以简化这个问题,并使代码更加简洁易读。
Optional Chaining 的用途
“Optional Chaining” 运算符(?.),使得代码可以处理对象的深嵌套属性、数组元素的访问、函数调用等情况。它提供了更优雅的方法来访问嵌套对象的属性。
在过去,如果你想要访问一个嵌套在另一个对象里的属性,你需要在访问每一个属性时检查上一个属性是否存在。
if (obj && obj.first && obj.first.second) { console.log(obj.first.second); }
其中 obj
可能不存在,或 first
属性也可能不存在,这样的检查可以显得非常冗长。使用 Optional Chaining 运算符却可以轻松的解决这个问题:
console.log(obj?.first?.second);
当属性 first
不存在时,代码将会通俗的返回 undefined
。这使得代码更加简洁,而且让其更容易阅读和理解。
另一个好处是,Optional Chaining 运算符使代码更加健壮,因为它能够处理可能出现的错误。
举个例子,如果想在 DOM 中获取一个元素,必须先检查父元素是否存在。如果这个父元素不存在,代码将会抛出一个错误。为了避免这种情况,可以使用 Optional Chaining 运算符:
const label = document.querySelector('label'); const input = label?.input; // 如果 label不存在,代码将不会抛出错误
在这个例子中,input
将被赋值为 undefined
,而不是抛出错误。如果 label
不存在,代码依然可以继续执行,而不是中断代码的执行。
同样,Optional Chaining 运算符也能够处理数组,使访问数组元素更容易:
const items = {}; const value = items?.[index]?.value;
上述代码将会首先处理 items
的存在。如果 index
值不存在,那么 value
将会返回 undefined
。
运用 Optional Chaining
了解了 Optional Chaining 的作用,那么如何在实际代码中运用呢?
假设有一个层级非常深的对象,我们需要获取到某个属性,代码会变成非常臃肿:
const country = countries && countries[0] && countries[0].address && countries[0].address.country;
使用 Optional Chaining,代码可以简化为:
const country = countries?.[0]?.address?.country;
这使得代码更易于阅读,同时也可以避免代码中的不必要的行间跳转。
对于异步非阻塞的代码流程,Optional Chaining 更显得出色。如果要加载一个文章对象,并且要访问其中的评论,代码可能会像下面这样:
fetch('/article/1') .then(response => response.json()) .then(article => { const comments = (article && article.data && article.data.comments) || []; // 使用 comments 对象 });
这样的代码流程显然有些冗长,使用 Optional Chaining 就可以简化为:
fetch('/article/1') .then(response => response.json()) .then(article => { const comments = article?.data?.comments || []; // 使用 comments 对象 });
总结
Optional Chaining 运算符是 ECMAScript 2018(ES9)的一个新特性,能够在访问嵌套对象属性时带来极大的便利性。使用它能够简化代码并加强代码的健壮性。除了访问对象属性外,Optional Chaining 运算符还可以用于访问数组元素、调用函数等。随着 ES9 的广泛使用,使用 Optional Chaining 运算符的代码也将更加普遍。
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/65a25588add4f0e0ffa74c9f