“AI 技术+人才”如何成为企业增长新引擎?戳此了解>>> 了解详情
写点什么

4 个强大 JavaScript 运算符

  • 2021-02-22
  • 本文字数:2713 字

    阅读完需:约 9 分钟

4个强大JavaScript运算符

今天我们学习新的 JS 运算符!


你有没有花一个下午的时间阅读 Mozilla 文档?如果有,你会发现网上有很多 JS 资料,这使我们很容易忽略那些更为基础的 JS 运算符。


这些运算符不常见但很强大!在语法上看起来很相似,作用却不一样,一定要仔细阅读。

1. ?? 非空运算符


在 JS 中,?? 运算符被称为非空运算符。如果第一个参数不是 null/undefined(译者注:这里只有两个假值,但是 JS 中假值包含:未定义 undefined、空对象 null、数值 0、空数字 NaN、布尔 false,空字符串’’,不要搞混了),将返回第一个参数,否则返回第二个参数。比如,


null ?? 5 // => 53 ?? 5 // => 3
复制代码


给变量设置默认值时,以前常用 ||逻辑或运算符,例如,


var prevMoney = 1var currMoney = 0var noAccount = nullvar futureMoney = -1function moneyAmount(money) {return money || `账户未开通`}console.log(moneyAmount(prevMoney)) // => 1console.log(moneyAmount(currMoney)) // => 账户未开通console.log(moneyAmount(noAccount)) // => 账户未开通console.log(moneyAmount(futureMoney)) // => -1
复制代码


上面我们创建了函数 moneyAmount,它返回当前用户余额。我们使用 || 运算符来识别没有帐户的用户。然而,当用户没有帐户时,这意味着什么?将无账户视为空而不是 0 更为准确,因为银行账户可能没有(或负)货币。在上面的例子中,|| 运算符将 0 视为一个虚假值,不应该包括用户有 0 美元的帐户。让我们使用?? 非空运算符来解决这个问题:


var currMoney = 0var noAccount = nullfunction moneyAmount(money) {  return money ?? `账户未开通`}moneyAmount(currMoney) // => 0moneyAmount(noAccount) // => `账户未开通`
复制代码


概括地说 ?? 运算符允许我们在忽略错误值(如 0 和空字符串)的同时指定默认值。

2. ??= 空赋值运算符


??= 也被称为空赋值运算符,与上面的非空运算符相关。看看它们之间的联系:


var x = nullvar y = 5console.log(x ??= y) // => 5console.log(x = (x ?? y)) // => 5
复制代码


仅当值为 null 或 undefined 时,此赋值运算符才会赋值。上面的例子强调了这个运算符本质上是空赋值的语法糖(译者注,类似的语法糖:a = a + b 可写成 a += b )。接下来,让我们看看这个运算符与默认参数(译者注,默认参数是 ES6 引入的新语法,仅当函数参数为 undefined 时,给它设置一个默认值)的区别:


function gameSettingsWithNullish(options) {  options.gameSpeed ??= 1  options.gameDiff ??= 'easy'   return options}function gameSettingsWithDefaultParams(gameSpeed=1, gameDiff='easy') {  return {gameSpeed, gameDiff}}gameSettingsWithNullish({gameSpeed: null, gameDiff: null}) // => {gameSpeed: 1, gameDiff: 'easy'}gameSettingsWithDefaultParams(undefined, null) // => {gameSpeed: null, gameDiff: null}
复制代码


上述函数处理空值的方式有一个值得注意的区别。默认参数将用空参数(译者注,这里的空参数,只能是 undefined)覆盖默认值,空赋值运算符将不会。默认参数和空赋值都不会覆盖未定义的值。更多信息请点击这里

3. ?. 链判断运算符


链判断运算符?. 允许开发人员读取深度嵌套在对象链中的属性值,而不必验证每个引用。当引用为空时,表达式停止计算并返回 undefined。比如:


var travelPlans = {  destination: 'DC',  monday: {    location: 'National Mall',    budget: 200  }}console.log(travelPlans.tuesday?.location) // => undefined
复制代码


现在,把我们刚刚学到的结合起来,把 tuesday 加入旅行计划中!


function addPlansWhenUndefined(plans, location, budget) {  if (plans.tuesday?.location == undefined) {    var newPlans = {      plans,      tuesday: {        location: location ?? "公园",        budget: budget ?? 200      },    }  } else {    newPlans ??= plans; // 只有 newPlans 是 undefined 时,才覆盖    console.log("已安排计划")  }  return newPlans}// 译者注,对象 travelPlans 的初始值,来自上面一个例子var newPlans = addPlansWhenUndefined(travelPlans, "Ford 剧院", null)console.log(newPlans)// => { plans: // { destination: 'DC',// monday: { location: '国家购物中心', budget: 200 } },// tuesday: { location: 'Ford 剧院', budget: 200 } }newPlans = addPlansWhenUndefined(newPlans, null, null)// logs => 已安排计划// returns => newPlans object
复制代码


上面的例子包含了我们到目前为止所学的所有运算符。现在我们已经创建了一个函数,该函数将计划添加到当前没有嵌套属性的对象 tuesday.location 中。我们还使用了非空运算符来提供默认值。此函数将错误地接受像“0”这样的值作为有效参数。这意味着 budget 可以设置为零,没有任何错误。

4. ?: 三元运算符


?: 又叫条件运算符,接受三个运算数:条件 ?  条件为真时要执行的表达式 : 条件为假时要执行的表达式。实际效果:


function checkCharge(charge) {  return (charge > 0) ? '可用' : '需充值' }console.log(checkCharge(20)) // => 可用console.log(checkCharge(0)) // => 需充值
复制代码


如果你写过 JS,可能见过三元运算符。但是,你知道三元运算符可以用于变量赋值吗?


var budget = 0var transportion = (budget > 0) ? '火车' : '步行' console.log(transportion) // => '步行'
复制代码


我们甚至可以用它来实现空赋值的行为:


var x = 6var x = (x !== null || x !== undefined) ? x : 3console.log(x) // => 6
复制代码


让我们通过创建一个函数来概括这个运算:


function nullishAssignment(x,y) {  return (x == null || x == undefined) ? y : x }nullishAssignment(null, 8) // => 8nullishAssignment(4, 8) // => 4
复制代码


在结束之前,让我们使用三元运算符重构前面示例中的函数:


function addPlansWhenUndefined(plans, location, budget) { var newPlans =   plans.tuesday?.location === undefined     ? {         plans,         tuesday: {           location: location ?? "公园",            budget: budget ?? 200         },       }     : console.log("已安排计划"); newPlans ??= plans; return newPlans;}
复制代码

结论


我们现在已经学习了这些运算符的使用方法,在这里有更多关于这些运算符的知识


(译者注:文中前三个运算符是 ES2020 的新特性,请勿直接用在生产环境, 可使用 webpack+babel 进行转义,解决浏览器兼容性问题)


原文链接:


https://medium.com/javascript-in-plain-english/4-powerful-javascript-operators-youve-never-heard-of-487df37114ad

2021-02-22 10:334633

评论 5 条评论

发布
用户头像
“前三个运算符是 ES2020 的新特性”,早点说啊!最后凑个?:,全文等于什么都没说!
2021-02-25 17:58
回复
用户头像
不加es版本的技术细节都是耍流氓~~
2021-02-24 09:12
回复
用户头像
这些需要babel支持吧。 还没有到 stage-4阶段吧?
2021-02-22 16:51
回复
用户头像
???
2021-02-22 09:24
回复
用户头像
怎么啥也没有😢?
2021-02-21 16:09
回复
没有更多了
发现更多内容

远程办公期间,项目小组微信群打卡 | 社区征文

IT蜗壳-Tango

6月月更 初夏征文

兼容10个浏览器HTML头部配置

写程序的小王叔叔

html 浏览器 浏览器插件 7月月更

Go Web 编程入门:一探 GoConvey 测试库

宇宙之一粟

Go web Go 语言 7月月更

远程办公如何保持高效协同,实现项目稳定增长 |社区征文

三掌柜

初夏征文 7月月更

架构实战营 毕业总结

热猫

密码学进阶(一):浅谈常见的七种加密算法及实现

No Silver Bullet

加密 文本摘要 数字签名 7月月更

投稿开奖丨轻量应用服务器征文活动(5月)奖励公布

阿里云弹性计算

nginx OSS MySQL 数据库 轻量征文

CleanMyMac X4.11最新版本号

茶色酒

CleanMyMac X

无需zookeeper安装kafka集群(kakfa3.0版本)

字母哥哥

大数据 kafka 消息队列

手把手带你快速入门Electron

是乃德也是Ned

7月月更

让企业数字化砸锅和IT主管背锅的软件供应链安全风险指北

FN0

安全性 沙箱实验 开源软件供应链

Ubuntu环境编译OpenJDK11源码

程序员欣宸

Java Openjdk 6月月更

面试必答题“聊聊Java中线程的生命周期状态”如何破?

博文视点Broadview

架构实战营 模块九:设计电商秒杀系统

热猫

云原生到底是什么?它会是未来发展的趋势吗?

Albert Edison

7月月更

软件产品管理平台有哪些?12个最佳产品管理工具盘点

PingCode

产品经理 产品管理 PingCode

【LeetCode】找树左下角的值Java题解

Albert

LeetCode 7月月更

Android Studio Arctic Fox | 2020.3.1、Gradle 7.0升级记录

yechaoa

android Android Studio Gradle 6月月更 AGP

主流实时流处理计算框架Flink初体验

百思不得小赵

大数据 flink 7月月更

数据中台咋就从“小甜甜”变成了“牛夫人”?

雨果

数据中台

rxjs Observable of 操作符的单步调试分析

Jerry Wang

typescript 前端开发 angular RXJS 7月月更

8253A寄存器浅析

乌龟哥哥

6月月更

Windbg调试工具介绍

dvlinker

c++ windbg 调试工具

一次革命、两股力量、三大环节:《工业能效提升行动计划》背后的“减碳”路线图

脑极体

电商秒杀系统

Dean.Zhang

什么是反向代理?Nginx反向代理如何配置?

wljslmz

nginx 反向代理 6月月更

《你的灯亮着吗》开始解决问题前,得先知道“真问题”是什么

图灵教育

使用GDIView工具排查GDI对象泄漏问题

dvlinker

c++ GDIView GDI对象泄露

HashMap分析-扩容

zarmnosaj

6月月更

leetcode 474. Ones and Zeroes 一和零(中等)

okokabcd

LeetCode 动态规划 算法与数据结构

这样的商城系统全开源免费商用,还要什么自行车!

CRMEB

4个强大JavaScript运算符_大前端_Anthony Jimenez_InfoQ精选文章