摘要:到年月,一个新的可选链提案已经进入第三阶段,这是一个很好的改进。可选链接改变了从深层对象结构访问属性的方式。咱们来看看可选链如何解决这个问题,以减少冗余的代码。该对象包含必填属性,以及可选的和。可选链运算符可防止抛出。
为了保证的可读性,本文采用意译而非直译。
想阅读更多优质文章请猛戳GitHub博客,一年百来篇优质文章等着你!
JS的一些特性极大地改变了咱们的编码方式。从ES6年开始,对咱们代码影响最大的特性的解 、箭头函数、类和模块系统。
到2019年8月,一个新的可选链提案已经进入第三阶段,这是一个很好的改进。可选链接改变了从深层对象结构访问属性的方式。
来看看这是又是什么骚操作。
这个礼拜《大迁世界》有抽奖活动,奖品:专栏 《左耳听风》 x3, 技术书 x5,欢迎关注回复:抽奖问题
由于JS的动态特性,对象可以具有多层不同的嵌套对象结构。
通常,当咱们处理以下这些对象时:
获取远程JSON数据
使用配置对象
有可选属性
虽然JS为对象支持不同层次数据结构,但是在访问此类对象的属性时,复杂性也随着增加。
bigObject可以在运行时拥有不同的属性集
// 嵌套版本 const bigObject = { // ... prop1: { //... prop2: { // ... value: "Some value" } } }; // 简单版本 const bigObject = { // ... prop1: { // Nothing here } };
因此,必须手动检查属性是否存在
if (bigObject && bigObject.prop1 != null && bigObject.prop1.prop2 != null) { let result = bigObject.prop1.prop2.value; }
这样写太过冗长了,最好避免写它。
咱们来看看可选链如何解决这个问题,以减少冗余的代码。
2. 易于深入访问属性设计一个保存电影信息的对象。 该对象包含必填title属性,以及可选的director和actors。
movieSmall对象仅包含title,而movieFull包含完整的属性集:
const movieSmall = { title: "Heat" }; const movieFull = { title: "Blade Runner", director: { name: "Ridley Scott" }, actors: [{ name: "Harrison Ford" }, { name: "Rutger Hauer" }] };
写一个获取director的函数。 请记住,director 可能不存在。
function getDirector(movie) { if (movie.director != null) { return movie.director.name; } } getDirector(movieSmall); // => undefined getDirector(movieFull); // => "Ridley Scott"
if(movie.director){...}条件用于验证是否定义了director属性。 如果没有这个预防措施,在访问movieSmall对象的director时,JS会抛出TypeError: Cannot read property "name" of undefined。
这种场景最适合使用可选链的功能了,如下所示,代码将简洁很多。
function getDirector(movie) { return movie.director?.name; } getDirector(movieSmall); // => undefined getDirector(movieFull); // => "Ridley Scott"
在movie.director?.name表达式中可以找到?.可选的链接操作符。
在movieSmall中,没有director属性。 因此,movie.director?.name的的结果为undefined。 可选链运算符可防止抛出 TypeError: Cannot read property "name" of undefined。
简单地说,代码片段:
let name = movie.director?.name;
等价于
let name; if (movie.director != null) { name = movie.director.name; }
?.通过减少两行代码简化getDirector()函数,这就是为什么我喜欢可选链的原因。
2.1 数组项可选的链功能可以做得更多。可以自由地在同一个表达式中使用多个可选的链接操作符,甚至可以使用它安全地访问数组项。
下一个任务是编写一个函数,返回电影的actors中的name。
在movie对象中,actors数组可以是空的,甚至是缺失的,因此必须添加额外的条件来判空。
function getLeadingActor(movie) { if (movie.actors && movie.actors.length > 0) { return movie.actors[0].name; } } getLeadingActor(movieSmall); // => undefined getLeadingActor(movieFull); // => "Harrison Ford"
if (movie.actors && movies.actors.length > 0) {...}条件主要判断movie包含actors属性,并且此属性至少有一个actor。
使用可选链接,同样代码也简洁了很了,如下:
function getLeadingActor(movie) { return movie.actors?.[0]?.name; } getLeadingActor(movieSmall); // => undefined getLeadingActor(movieFull); // => "Harrison Ford"
actors?. 确保actors属性存在, [0]?.确保列表中存在第一个actor。
3.双问号操作符一个名为nullish coalescing operator的新提议? 处理undefined或null,将它们默认为特定值。
表达式变量?? 如果变量undefined或为null,则默认值为指定的值。
const noValue = undefined; const value = "Hello"; noValue ?? "Nothing"; // => "Nothing" value ?? "Nothing"; // => "Hello"
接着使用??来优化一下 getLeading()函数,当movie对象中没有actor时返回“Unknown actor”
function getLeadingActor(movie) { return movie.actors?.[0]?.name ?? "Unknown actor"; } getLeadingActor(movieSmall); // => "Unknown actor" getLeadingActor(movieFull); // => "Harrison Ford"4. 可选链的三种形式
咱们可以使用以下3种形式的可选链。
第一种: object?.property 用于访问静态属性:
const object = null; object?.property; // => undefined
第二种:object?.[expression] 用于访问动态属性或数组项:
// 其一 const object = null; const name = "property"; object?.[name]; // => undefined // 其二 const array = null; array?.[0]; // => undefined
第三种:object?.([arg1, [arg2, ...]]) 执行一个对象方法
const object = null; object?.method("Some value"); // => undefined
将这三种组合起来创建一个可选链:
const value = object.maybeUndefinedProp?.maybeNull()?.[propName];5.短路:遇到 null/undefined 停止
可选链接运算符的有趣之处在于,只要在左侧leftHandSide?.rightHandSide遇到无效值,右侧访问就会停止,这称为短路。
看看例子:
const nothing = null; let index = 0; nothing?.[index++]; // => undefined index; // => 06. 何时使用可选链
不要急于使用可选的链操作符来访问任何类型的属性:这会导致错误的使用。
6.1访问潜在无效的属性?.一般使用在可能为空的属性:maybeNullish?.prop。在确定属性不为空的情况下,使用属性访问器:.property或[propExpression]。
// 好 function logMovie(movie) { console.log(movie.director?.name); console.log(movie.title); } // 不好 function logMovie(movie) { // director needs optional chaining console.log(movie.director.name); // movie doesn"t need optional chaining console.log(movie?.title); }6.2 通常有更好的选择
以下函数hasPadding()接收可选padding属性的样式对象。 padding具有left,top,right,bottom可选属性。
尝试使用可选的链操作符:
function hasPadding({ padding }) { const top = padding?.top ?? 0; const right = padding?.right ?? 0; const bottom = padding?.bottom ?? 0; const left = padding?.left ?? 0; return left + top + right + bottom !== 0; } hasPadding({ color: "black" }); // => false hasPadding({ padding: { left: 0 } }); // => false hasPadding({ padding: { right: 10 }}); // => true
虽然函数正确地确定了元素是否有padding,但是对于每个属性使用可选的链有点过于麻烦了。
更好的方法是使用对象扩展操作符将padding对象默认为零值
function hasPadding({ padding }) { const p = { top: 0, right: 0, bottom: 0, left: 0, ...padding }; return p.top + p.left + p.right + p.bottom !== 0; } hasPadding({ color: "black" }); // => false hasPadding({ padding: { left: 0 } }); // => false hasPadding({ padding: { right: 10 }}); // => true
这个就比可选链来的更简洁。
代码部署后可能存在的BUG没法实时知道,事后为了解决这些BUG,花了大量的时间进行log 调试,这边顺便给大家推荐一个好用的BUG监控工具 Fundebug。
原文:https://dmitripavlutin.com/ja...
交流干货系列文章汇总如下,觉得不错点个Star,欢迎 加群 互相学习。
https://github.com/qq44924588...
我是小智,公众号「大迁世界」作者,对前端技术保持学习爱好者。我会经常分享自己所学所看的干货,在进阶的路上,共勉!
关注公众号,后台回复福利,即可看到福利,你懂的。
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/106986.html
摘要:今天决定给自己的站点配置,配置完成后发现不能正常访问,思来想去发现是未开启端口。这也是不指定规则序号时的默认方式。参数给出一个合法的目标。给出当前命令语法非常简短的说明。 今天决定给自己的站点配置SSL,配置完成后发现不能正常访问,思来想去发现是未开启443端口。 Linux防火墙开放特定端口 方法一 找到/etc/sysconfig/iptables文件加入如下代码,并保存 -A I...
摘要:如果大家阅读过我之前写的一篇关于解构的文章,那一定会了解到解构达到数据防御功能,那么本文要介绍的是另一种数据防御方式可选链。什么是允许我们检查对象是否存在,然后才试图访问它的属性。如何使用目前在阶段。 如果大家阅读过我之前写的一篇关于ES6解构的文章,那一定会了解到解构达到数据防御功能,那么本文要介绍的是另一种数据防御方式Optional Chaining(可选链)。 什么是Optio...
阅读 1071·2021-10-09 09:43
阅读 18274·2021-09-22 15:52
阅读 1042·2019-08-30 15:44
阅读 3030·2019-08-30 15:44
阅读 3222·2019-08-26 14:07
阅读 891·2019-08-26 13:55
阅读 2548·2019-08-26 13:41
阅读 3064·2019-08-26 13:29