发布在即!企业 AIGC 应用程度测评,3 步定制专属评估报告。抢首批测评权益>>> 了解详情
写点什么

了解 JavaScript 新特性:Optional Chaining

  • 2019-10-25
  • 本文字数:2083 字

    阅读完需:约 7 分钟

了解JavaScript新特性:Optional Chaining

Optional Chaining 是 JavaScript 的一个新特性,它允许我们在尝试访问对象的属性之前检查对象是否存在。其他语言也有类似的东西,例如,C# 的 Null Conditional 操作符,与 Optional Chaining 非常类似。


JavaScript 中的长属性访问链很容易出错,因为它们中的任何一个都可能评估为nullundefined(也称为“空”值)。要在每个步骤都中检查属性是否存在,很容易搞出来一个深层嵌套结构的if语句或一个长长的if条件复制属性访问链:


// Error prone-version, could throw.const nameLength = db.user.name.length;
// Less error-prone, but harder to read.let nameLength;if (db && db.user && db.user.name) nameLength = db.user.name.length;
复制代码


上面的代码也可以使用三元操作符表示,但并不能提高可读性。


const nameLength =  (db    ? (db.user      ? (db.user.name        ? db.user.name.length        : undefined)      : undefined)    : undefined);
复制代码

介绍 Optional Chaining 操作符

你当然不想编写这样的代码,因此希望有其他选择。其他一些语言使用了被称为“optional chaining”(可选链)的功能提供了一种优雅的解决方案。根据最近的规范提案,“Optinal Chain 是一个或多个属性访问和函数调用的链,其中第一个以令牌?.开头”。


使用新的 Optinal Chaining 操作符,我们可以重写上述示例,如下所示:


// Still checks for errors and is much more readable.const nameLength = db?.user?.name?.length;
复制代码


如果dbusernameundefinednull会发生什么?使用 Optinal Chaining 操作符时,JavaScript 会将nameLength初始化为undefined,而不是抛出错误。


请注意,此行为也比我们检查if (db && db.user && db.user.name)更加健壮。例如,如果name一直都是字符串怎么办?我们可以将name?.length更改为name.length。如果name是一个空字符串,我们仍将获得正确的0长度。这是因为空字符串是虚值:它在if子句中的行为类似false。Optinal Chaining 操作符可修复这类常见的错误。

其他语法形式:调用和动态属性

还有一个用来调用可选方法的操作符版本:


// Extends the interface with an optional method, which is present// only for admin users.const adminOption = db?.user?.validateAdminAndGetPrefs?.().option;
复制代码


这里的语法可能让人感到意外,因为?.()是实际的操作符,它适用于 之前 的表达式。


操作符还有第三种用法,就是可选的动态属性访问,通过?.[]实现。它要么返回括号中的参数所引用的值,或者如果没有可以获取值的对象,则返回undefined。按照上面的示例,下面是一个可能的用例:


// Extends the capabilities of the static property access// with a dynamically generated property name.const optionName = 'optional setting';const optionLength = db?.user?.preferences?.[optionName].length;
复制代码


最后一种形式也可用于可选的索引数组,例如:


// If the `usersArray` is `null` or `undefined`,// then `userName` gracefully evaluates to `undefined`.const userIndex = 42;const userName = usersArray?.[userIndex].name;
复制代码


需要非undefined默认值时,Optinal Chaining 操作符可以与双问号?? 操作符组合使用。这样可以使用指定的默认值进行安全的深层属性访问,从而解决了以前需要用户域库(例如 lodash 的 _.get)的常见用例:


const object = { id: 123, names: { first: 'Alice', last: 'Smith' }};
{ // With lodash: const firstName = _.get(object, 'names.first'); // → 'Alice'
const middleName = _.get(object, 'names.middle', '(no middle name)'); // → '(no middle name)'}
{ // With optional chaining and nullish coalescing: const firstName = object?.names?.first ?? '(no first name)'; // → 'Alice'
const middleName = object?.names?.middle ?? '(no middle name)'; // → '(no middle name)'}
复制代码

Optinal Chaining 操作符的属性

Optinal Chaining 操作符具有一些有趣的属性:短路、堆叠和可选删除。下面通过一个示例逐一介绍。


短路(Short-circuiting)意味着如果 Optinal Chaining 操作符提前返回,则不对表达式的其余部分求值:


// `age` is incremented only if `db` and `user` are defined.db?.user?.grow(++age);
复制代码


堆叠(Stacking)意味着可以对一系列属性访问应用多个 Optinal Chaining 操作符:


// An optional chain may be followed by another optional chain.const firstNameLength = db.users?.[42]?.names.first.length;
复制代码


尽管如此,在一条链中使用多个 Optinal Chaining 操作符前请三思。如果一个值保证不为空,则不建议使用?.访问它的属性。在上面的示例中,db被视为始终已定义,但是db.usersdb.users [42]可能未定义。如果数据库中有这样的用户,则假定始终定义names.first.length


可选删除(Optinal deletion)意味着可以将delete操作符与 Optinal Chain 结合使用:


// `db.user` is deleted only if `db` is defined.delete db?.user;
复制代码


更多信息参阅提案的语义部分


原文链接https://v8.dev/features/optional-chaining


2019-10-25 19:484134

评论

发布
暂无评论
发现更多内容

「直播回放」使用 PLC + OPC + TDengine,快速搭建烟草生产监测系统

TDengine

tdengine 时序数据库

做好这4点,面试嘎嘎猛~

王磊

Java 面试

知识图谱与大模型结合方法概述

华为云PaaS服务小智

云计算 软件开发 华为云

软件测试|Python列表的使用,你都会了吗?(一)

霍格沃兹测试开发学社

软件测试|超好用超简单的Python GUI库——tkinter

霍格沃兹测试开发学社

一文讲透DevOps理论体系的演进 | 京东云技术团队

京东科技开发者

DevOps 自动化 DevOps工具

Luminar Neo(超强AI图像编辑器)特别版下载mac/win

影影绰绰一往直前

Luminar Neo破解版 Luminar Neo下载 Luminar Neo mac

AI PC的时代,英特尔和联想、爱奇艺是怎样玩转AI的?

E科讯

稳定扩散的高分辨率图像合成

3D建模设计

AI自动纹理 稳定扩散

科技企业正成为外交名片

TE智库

新能源

去中心化交易所开发

西安链酷科技

区块链 去中心化 交易所 合约 合约数字货币

重磅更新!Sermant 1.2.0 release版本新特性速览

华为云开发者联盟

开源 后端 华为云 华为云开发者联盟

LRTimelapse for mac(延时摄影视频制作) 6.5.2中文激活版

mac

苹果mac Windows软件 lrTimelapse 延时摄影视频制作软件

7 款用于训练 AI 模型的合成数据工具

3D建模设计

人工智能模型 合成数据 UnrealSynth

数字货币 链上挖矿模式开发

西安链酷科技

区块链 数字货币 dapp 挖矿 合约

校园跑腿

图颜有信

「燃情大促,年终钜惠」,家人们这一波可以冲!

融云 RongCloud

活动 服务 IM RTC 融云

Java应用程序性能开发工具:JProfiler 14 「Mac」附 注册码

彩云

java开发工具 JProfiler 14

PDF编辑器:Acrobat Pro DC 2023 「Mac」

彩云

PDF编辑 Acrobat Pro DC 2023

DAPP链上质押挖矿分红开发原理

西安链酷科技

区块链 dapp 去中心化 挖矿

云平台是否支持黑白相机拍摄的灰度图?

矩视智能

深度学习 黑白相机

AI 革命:最佳 txt 转纹理工具

3D建模设计

AI自动纹理 AI纹理

大数据与 AI 的双向奔赴|创原会畅聊云原生第12期·作者光临

华为云原生团队

云计算 容器 云原生 分享 创原会

SaaS 出海,如何搭建国际化服务体系?(二)

LigaAI

经验总结 To B业务 出海 SaaS 产品 SaaS 增长

如何使用 NFTScan NFT API 在 Ethereum 网络上开发 Web3 应用

NFT Research

NFT\ nft工具

服务器大揭秘:美国服务器为何成为热门选项?

一只扑棱蛾子

美国服务器

软件测试|Python列表的使用,你都会了吗?(二)

霍格沃兹测试开发学社

当我们在谈论构造函数注入的时候我们在谈论什么 | 京东物流技术团队

京东科技开发者

Java 面向对象 构造函数 依赖注入 函数注入

ps插件:alpaca增效工具 (完美替代AI创成式填充)

iMac小白

alpaca下载 alpaca增效工具

ARBT质押挖矿DAPP系统开发(源码搭建)

l8l259l3365

2023年10月文章一览

codists

了解JavaScript新特性:Optional Chaining_大前端_Maya Lekova_InfoQ精选文章