javascript 可选链 “?.”

可选链 ?. 是一种访问嵌套对象属性的安全的方式。即使中间的属性不存在,也不会出现错误。

“不存在的属性”的问题

如果你才刚开始读此教程并学习 JavaScript,那可能还没接触到这个问题,但它却相当常见。

举个例子,假设我们有很多个 user 对象,其中存储了我们的用户数据。

我们大多数用户的地址都存储在 user.address 中,街道地址存储在 user.address.street 中,但有些用户没有提供这些信息。

在这种情况下,当我们尝试获取 user.address.street,而该用户恰好没提供地址信息,我们则会收到一个错误:

这是预期的结果。JavaScript 的工作原理就是这样的。因为 user.addressundefined,尝试读取 user.address.street 会失败,并收到一个错误。

但是在很多实际场景中,我们更希望得到的是 undefined(表示没有 street 属性)而不是一个错误。

……还有另一个例子。在 Web 开发中,我们可以使用特殊的方法调用(例如 document.querySelector('.elem'))以对象的形式获取一个网页元素,如果没有这种对象,则返回 null

同样,如果该元素不存在,则访问 null.innerHTML 时会出错。在某些情况下,当元素的缺失是没问题的时候,我们希望避免出现这种错误,而是接受 html = null 作为结果。

我们如何实现这一点呢?

可能最先想到的方案是在访问该值的属性之前,使用 if 或条件运算符 ? 对该值进行检查,像这样:

这样可以,这里就不会出现错误了……但是不够优雅。就像你所看到的, "user.address" 在代码中出现了两次。对于嵌套层次更深的属性就会出现更多次这样的重复,这就是问题了。

例如,让我们尝试获取 user.address.street.name

我们既需要检查 user.address,又需要检查 user.address.street

这样就太扯淡了,并且这可能导致写出来的代码很难让别人理解。

甚至我们可以先忽略这个问题,因为我们有一种更好的实现方式,就是使用 && 运算符:

依次对整条路径上的属性使用与运算进行判断,以确保所有节点是存在的(如果不存在,则停止计算),但仍然不够优雅。

就像你所看到的,在代码中我们仍然重复写了好几遍对象属性名。例如在上面的代码中, user.address 被重复写了三遍。

这就是为什么可选链 ?. 被加入到了 JavaScript 这门编程语言中。那就是彻底地解决以上所有问题!

可选链

如果可选链 ?. 前面的值为 undefined 或者 null,它会停止运算并返回 undefined

为了简明起见,在本文接下来的内容中,我们会说如果一个属性既不是 null 也不是 undefined ,那么它就”存在”。

换句话说,例如 value?.prop

  • 如果 value 存在,则结果与 value.prop 相同,
  • 否则(当 valueundefined/null 时)则返回 undefined

下面这是一种使用 ?. 安全地访问 user.address.street 的方式:

代码简洁明了,也不用重复写好几遍属性名。

即使 对象 user 不存在,使用 user?.address 来读取地址也没问题:

请注意: ?. 语法使其前面的值成为可选值,但不会对其后面的起作用。

例如,在 user?.address.street.name 中, ?. 允许 usernull/undefined(在这种情况下会返回 undefined)也不会报错,但这仅对于 user。更深层次的属性是通过常规方式访问的。如果我们希望它们中的一些也是可选的,那么我们需要使用更多的 ?. 来替换 .

短路效应

正如前面所说的,如果 ?. 左边部分不存在,就会立即停止运算(”短路效应”)。

所以,如果后面有任何函数调用或者副作用,它们均不会执行。

例如:

其它变体:?.(),?.[]

可选链 ?. 不是一个运算符,而是一个特殊的语法结构。它还可以与函数和方括号一起使用。

例如,将 ?.() 用于调用一个可能不存在的函数。

在下面这段代码中,有些用户具有 admin 方法,而有些没有:

在这两行代码中,我们首先使用点符号( userAdmin.admin)来获取 admin 属性,因为我们假定对象 userAdmain 存在,因此可以安全地读取它。

然后 ?.() 会检查它左边的部分:如果 admin 函数存在,那么就调用运行它(对于 userAdmin)。否则(对于 userGuest)运算停止,没有报错。

如果我们想使用方括号 [] 而不是点符号 . 来访问属性,语法 ?.[] 也可以使用。跟前面的例子类似,它允许从一个可能不存在的对象上安全地读取属性。

此外,我们还可以将 ?.delete 一起使用:

可选链 ?. 语法有三种形式:

正如我们所看到的,这些语法形式用起来都很简单直接。 ?. 检查左边部分是否为 null/undefined,如果不是则继续运算。

?. 链使我们能够安全地访问嵌套属性。

但是,我们应该谨慎地使用 ?.,仅在当左边部分不存在也没问题的情况下使用为宜。以保证在代码中有编程上的错误出现时,也不会对我们隐藏。

Original: https://www.cnblogs.com/ryanzheng/p/15847480.html
Author: Ryan_zheng
Title: javascript 可选链 “?.”

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/535912/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • JavaScript 实现 Base64

    1、引入Base64.js Html中引入: VUE中引入: 使用: 如果与后端交互,请参考这篇文章: Original: https://www.cnblogs.com/hunt…

    JavaScript 2023年5月29日
    040
  • 生活无奈javascript

    1、substring 和 substr的区别。substring(indexA,indexB).很怪的。从小的开始,到大的结束。不管AB的顺序。substr(Location,s…

    JavaScript 2023年5月29日
    043
  • 你不知道的 JavaScript 系列中( 29 ) - == 和 ===

    说到 == 和 === 的区别,常见的误区是”== 检查值是否相等,=== 检查值和类型是否相等”。听起来蛮有道理,然而还不够准确。很多 JavaScrip…

    JavaScript 2023年5月29日
    066
  • JavaScript – 冷知识 (新手)

    当 charAt 遇上 Emoji 参考: stackoverflow – How to get first character of string? 我们经常会用 charAt(…

    JavaScript 2023年5月29日
    057
  • 【JavaScript系列】之零:TypeScript牛刀小试

    基于对JavaScript编程语言的好奇,在查看相关资料时,看到已经出现了一个更好的编程语言:TypeScript。下面简单介绍一下这个编程语言,作为JavaScript系列的开篇…

    JavaScript 2023年5月29日
    055
  • javascript算法-插入排序

    原理跟java那篇文章一样,只是语言不同而已 var InsertSort = function( _n ){ this.maxSize = _n; this.arr = []; …

    JavaScript 2023年5月29日
    089
  • JavaScript 是如何运行的?

    摘要: 理解JS执行原理。 原文:JavaScript 是如何运行的? 作者:hengg Fundebug 经授权转载,版权归原作者所有。 什么是JavaScript? 我们来确认…

    JavaScript 2023年5月29日
    088
  • 全栈JavaScript之路(十九)HTML5 插入 html标记 ( 一 )innerHTML 与outerHTML

    在须要给文档插入大量的html 标记下。通过DOM操作非常麻烦,你不仅要创建一系列的节点,并且还要小心地依照顺序把它们接结起来。 利用html 标签 插入技术,能够直接插入html…

    JavaScript 2023年5月29日
    065
  • JavaScript 图片滑动切换效果

    序一(08/07/06) 看到alibaba的一个图片切换效果,感觉不错,想拿来用用。但代码一大堆的,看着昏,还是自己来吧。由于有了做图片滑动展示效果的经验,做这个就容易得多了。 …

    JavaScript 2023年5月29日
    058
  • JavaScript编码规范

    ———————- 加微信和老王聊技术、聊产品、 聊运营。 定期组织主题性远程语音讨论。 进群加微…

    JavaScript 2023年5月29日
    065
  • Javascript技巧

    Javascript数组转换为CSV格式 首先考虑如下的应用场景,有一个Javscript的字符型(或者数值型)数组,现在需要转换为以逗号分割的CSV格式文件。则我们可以使用如下的…

    JavaScript 2023年5月29日
    058
  • JavaScript 同步异步示意图

    posted @2017-07-24 08:48 一个勤奋的胖子 阅读(839 ) 评论() 编辑 Original: https://www.cnblogs.com/ys-wuh…

    JavaScript 2023年5月29日
    048
  • 一张图带你搞懂Javascript原型链关系

    在某天,我听了一个老师的公开课,一张图搞懂了原型链。 老师花两天时间理解、整理的,他讲了两个小时我们当时就听懂了。 今天我把他整理出来,分享给大家。也让我自己巩固加深一下。 就是这…

    JavaScript 2023年5月29日
    066
  • 理解Javascript执行过程

    Javascript是一种解释型的动态语言。 在程序中,有编译型语言和解释型语言。那么什么是编译型语言,什么是解释型语言呢? 编译型语言: 它首先将源代码编译成机器语言,再由机器运…

    JavaScript 2023年5月29日
    048
  • “5W1H”带你来学习JavaScript

    上次的设计模式讲课,从中学习到了非常多。不仅是技术上,更重要的是怎样来学习。我们学习的技术。科技的更新速度超过我们的想象,对于我们这个有生命年限的个体,怎样可以在有生之年可以让自己…

    JavaScript 2023年5月29日
    070
  • 深入理解 JavaScript 异步系列(1)——基础

    前言 2014年秋季写完了《深入理解javascript原型和闭包系列》,已经帮助过很多人走出了 js 原型、作用域、闭包的困惑,至今仍能经常受到好评的留言。 很早之前我就总结了J…

    JavaScript 2023年5月29日
    055
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球