4个强大JavaScript运算符

2023-05-16

作者 | Anthony Jimenez

译者 | 吴留坡

策划 | 田晓旭

来源 | 前端之巅

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

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

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

1. ?? 非空运算符

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

null ?? 5 // => 5
3 ?? 5 // => 3

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

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

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

var currMoney = 0
var noAccount = null
function moneyAmount(money) {
  return money ?? `账户未开通`
}
moneyAmount(currMoney) // => 0
moneyAmount(noAccount) // => `账户未开通`

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

2. ??= 空赋值运算符

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

var x = null
var y = 5
console.log(x ??= y) // => 5
console.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)覆盖默认值,空赋值运算符将不会。默认参数和空赋值都不会覆盖未定义的值。更多:

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Logical_nullish_assignment

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 = 0
var transportion = (budget > 0) ? '火车' : '步行' 
console.log(transportion) // => '步行'

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

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

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

function nullishAssignment(x,y) {
  return (x == null || x == undefined) ? y : x 
}
nullishAssignment(null, 8) // => 8
nullishAssignment(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;
}

    结论    

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

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators

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

 延伸阅读

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

❤️爱心三连击

1.看到这里了就点个在看支持下吧,你的「点赞,在看」是我创作的动力。
2.关注公众号【程序员成长指北】,回复「1」加入高级前端交流群!「在这里有好多 前端 开发者,会讨论 前端 Node 知识,互相学习」!
3.也可添加微信【ikoala520】,一起成长。

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

4个强大JavaScript运算符 的相关文章

  • 我如何能够以两行显示标题,并且每行的字体大小不同?

    我正在使用 Google Chart API 创建时间线图 并希望将图的标题修改为两行 问题 我如何能够显示具有不同字体大小的两线图表标题 电流输出 理想输出 相关研究 我唯一能找到的是有人试图用饼图来做到这一点 但我尝试了但无法使其发挥作
  • 由于 apollo-client 未定义,无法解构 GraphQL 查询?

    我正在寻找调试与错误消息相关的问题 未捕获的类型错误 无法解构 0 apollo client WEBPACK IMPORTED MODULE 4 useQuery 因为它未定义 Context 我正在为我的 React js 项目设置后端
  • 暂停除了已激活的玩家之外的所有其他玩家。

    我有这个插件 它可以将不同的样式应用于 html5
  • Chart.js 在初始化时设置活动段

    我正在使用 Chart js v2 并且尝试在加载图表时模拟圆环图上某个段的 悬停状态 因此看起来有一个部分已突出显示 我已经搜索和梳理了代码一天 但找不到一个好的方法来做到这一点 提前致谢 设置片段的悬停样式有点令人困惑 因为它没有真正记
  • IE从哪个版本开始支持Object.create(null)?

    您可以通过多种方式在 JavaScript 中创建对象 creates an object which makes the Object prototype of data var data1 new Object Object liter
  • Draggable JS Bootstrap 模式 - 性能问题

    对于工作中的项目 我们在 JavaScript 中使用 Bootstrap Modal 窗口 我们想让一些窗口可移动 但我们遇到了 JQuery 的性能问题 myModal draggable handle modal header Exa
  • 如何将函数附加到弹出窗口关闭事件(Twitter Bootstrap)

    我做了一些搜索 但我只能认为我可以将事件附加到导致其关闭的按钮 https stackoverflow com questions 13205103 attach event handler to button in twitter boo
  • 尝试将数据存储在点击器网站中

    我正在尝试存储一个名为的变量score无论何时刷新 您都会一次又一次地使用它 我不明白的是它的代码是什么 我尝试了一些方法 但似乎都不起作用 这是我的答题器网站 但是当我尝试使用 JavaScript 来存储它时 它不起作用window o
  • window.location 和 location.href 之间的区别

    我对之间的区别感到困惑window location and location href 两者似乎都以相同的方式行事 有什么不同 window location是一个对象 它保存有关当前文档位置的所有信息 主机 href 端口 协议等 lo
  • 刷新页面时保存用户的选择

    我目前有一个页面显示不同团队的数据 我有一些数据 用户可以单击使其处于 打开 或 关闭 状态 并为每个数据显示不同的图标 它基本上就像一个清单 只是没有物理复选框 我想记住哪些 复选框 已被选中 即使在用户刷新页面或关闭浏览器并稍后返回之后
  • 将 UMD Javascript 模块导入浏览器

    你好 我正在对 RxJS 进行一些研究 我可以通过在浏览器中引用它来使用该库 如下所示 它使用全局对象命名空间变量 Rx 导入 我可以制作可观察的东西并做所有有趣的事情 当我将 src 更改为指向最新的 UMD 文件时 一切都会崩溃 如下所
  • 页面上使用 HTML Editor Extender 进行回发会导致 IE11 中出现 JavaScript 错误

    我已将 HTML 编辑器扩展程序添加到我正在处理的页面中 现在每当我在页面上发回帖子时 都会收到以下 Javascript 错误 JavaScript 运行时错误 参数无效 之后什么也没有发生 这在 IE10 或更低版本以及我所知道的所有其
  • Firebase 函数 onWrite 未被调用

    我正在尝试使用 Firebase 函数实现一个触发器 该触发器会复制数据库中的一些数据 我想观看所有添加的内容votes user vote 结构为 我尝试的代码是 const functions require firebase func
  • 从数据库检查数据的异步解决方案各种循环子句

    我想要做的是异步检查数据库并从中获取结果 在我的应用程序中我试图实现Asynchronously将此步骤解决为 从数据库中检查手机号码JsonArray循环子句的种类 Create JsonArray从结果 打印创建的数组 我学到了足够多的
  • Three.js 各种大小的粒子

    我是 Three js 的新手 正在尝试找出添加 1000 个粒子的最佳方法 每个粒子都有不同的大小和颜色 每个粒子的纹理是通过绘制画布创建的 通过使用粒子系统 所有粒子都具有相同的颜色和大小 为每个粒子创建一个粒子系统是非常低效的 有没有
  • 使用 Vue 的多模式组件

    我在 Vue 中实现动态模式组件时遇到问题 A common approach I follow to display a set of data fetched from the db is I dump each of the rows
  • Vue 和 Vuex:处理依赖的计算属性

    我的应用程序是一个使用 Vuex 在 Vue 中构建的精简电子表格 关键组件是TableCollection Table and Row The TableCollection有一个包含多个的数组Table对象 每个Table有一个包含多个
  • 用于交互式图形绘制的轻量级 JavaScript 库? [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我有兴趣了解用于绘制交互式图表的最轻量级 javascript 库 我掌握的数据主要是与海洋研究相关的科学数据 我知道一些 jquery
  • 使用 MongoDB 和 Nodejs 插入和查询日期

    我需要一些帮助在 mongodb 和 nodejs 中按日期查找记录 我将日期添加到抓取脚本中的 json 对象 如下所示 jsonObj last updated new Date 该对象被插入到 mongodb 中 我可以看到如下 la
  • 如何在react-highcharts中使用图表工具提示格式化程序?

    如何使用图表工具提示格式化程序 我正在使用高图表的反应包装器 我有这样的配置 const CHART CONFIG tooltip formatter tooltip gt var s b this x b each this points

随机推荐

  • 怎样学好数电

    随着社会的进步和科学技术的发展 xff0c 数字系统和数字设备已广泛应用于各个领域 xff0c 大规模 xff0c 超大规模集成电路技术的不断完善使得数字电路在现代电子系统的比重越来越大 xff0c 数字电路建立了根本是信号的数字处理 xf
  • 嵌入式经典面试题之选择题

    一 单项选择题 1 如下哪一个命令可以帮助你知道shell命令的用法 xff08 A xff09 A man B pwd C help D more 2 Linux分区类型默认的是 xff1a xff08 B xff09 A vfat B
  • 自定义 Windows RE 体验

    发布时间 2009年10月 更新时间 2009年10月 应用到 Windows 7 Windows Server 2008 R2 https technet microsoft com zh cn library dd744576 v 61
  • Java命令行运行错误: 找不到或无法加载主类

    前言 xff1a 虽然学习Java语言约有两年多 xff0c 但在最近需要使用命令行工具编译并运行Java程序时 xff0c 还是报错了 花费了一些时间 xff0c 解决了该问题 xff0c 发现解决方法在初学Java时使用过 一则 xff
  • 开贴记录STM32工程遇到的各种问题及解决方法

    开贴记录STM32工程遇到的各种问题及解决方法 STM32工程问题集锦 针对工程开发过程中常见问题进行备注 文章目录 STM32工程问题集锦问题列表时钟设置串口设置STM32CUBEIDEADCDMA定时器HardFault 处理方法时钟设
  • [1040]DataWorks中MaxCompute的常用操作命令

    文章目录 表操作1 查看表的详细信息 xff1a 2 通过 96 create table as select 96 语句创建表 xff0c 并在建表的同时将数据复制到新表中 xff1a 3 如果希望源表和目标表具有相同的表结构 xff0c
  • [549]python实现K-Means算法

    K Means是一种聚类 Clustering 算法 xff0c 使用它可以为数据分类 K代表你要把数据分为几个组 xff0c 前文实现的K Nearest Neighbor算法也有一个K xff0c 实际上 xff0c 它们有一个相似之处
  • 串口调试工具开发

    刚学习Qt xff0c 搜查资料 xff0c 根据学到的知识 xff0c 完成一个简单的串口调试工具 刚入行 xff0c 谅解 最终效果图 xff0c 图上功能都可实现 UI界面绘制 xff1a 代码如下 xff1a 串口调试工具开发 1
  • (illegal character encoding in string literal)解决乱码问题

    打开项目显示 xff08 xfffd xfffd xfffd xfffd xff09 乱码 xff0c 警告 xff0c 都是因为文本编码格式 选择合适的文本编码即可
  • “Failed to get convolution algorithm. This is probably because cuDNN failed to initialize”错误解决方案

    最近在使用TF2 0 运行程序出现以下错误 Failed to get convolution algorithm This is probably because cuDNN failed to initialize 一开始怀疑是CUDA
  • 程序员学习能力提升三要素

    IT技术的发展日新月异 xff0c 新技术层出不穷 xff0c 具有良好的学习能力 xff0c 能及时获取新知识 随时补充和丰富自己 xff0c 已成为程序员职业发展的核心竞争力 多年的学习经验总结出了提高程序员学习能力的三个要点 学习人人
  • Unable to determine the device handle for GPU. GPU is lost. Reboot the system to recover this GPU.

    最近服务器跑程序的时候经常出现GPU lost的情况 xff0c 报错信息如下 xff1a Unable to determine the device handle span class token keyword for span GP
  • 安装matlab的R2017b或者R2018a版本注意事项

    如果我们目前使用的是win10系统 xff0c 并且正确地按照网上安装并激活matlab的R2017b或者R2018a版本 xff0c 但是运行matlab时仍然会报错的情况 xff0c 报错内容是License Manager Error
  • IP地址0.0.0.0表示什么

    声明 xff1a 尊重原创 xff0c 查看原文请点击 IP地址0 0 0 0表示什么 转发目的为了构建 计算机网络 专栏 xff0c 收集相关优秀文章 xff0c 并创建自己的文章 方便自己和他人系统的学习相关知识 xff0c 感谢原文
  • Android群英传——第九章packages.xml的作用

    Android系统在初始化时 xff0c PackageManager的底层实现类PackageManagerService 回去扫描系统的 data system 目录下的packages xml文件 xff0c 这个文件包含了所有的ap
  • 百思不得姐之图片处理(保存与下载)

    一 功能图 二 讲解思路 1 回顾上一篇内容 2 创建加载图片类 同时创建xib 3 点击图片查看大图 4 点击查看大图 查看长图 5 model出展示图片的控制器 6 保存图片 7 封装根据网络状态展示不同的图片 三 回顾上一篇内容 1
  • 路由器电路(高清图)

    路由器正面 路由器背面
  • 技术4面+HR面,花了一个半月的时间准备,终于上岸阿里测开岗

    这次阿里的面试 xff0c 给我的感触很深 xff0c 意识到基础的重要性 一共经历了五轮面试 xff1a 技术4面 xff0b HR面 下面看正文 本人自动化专业毕业 xff0c 压抑了五个多月 xff0c 终于鼓起勇气 xff0c 去阿
  • 5个实用的性能测试工具(软件测试工程师必备)

    在日常的软件测试工作中 xff0c 最常用的性能测试工具是LoadRunner和Jmeter 今天给大家整理了5个针对web应用程序性能和负载压力能力的最广泛使用的性能测试工具 这几个负载测试工具将确保应用程序在高峰流量和极端压力条件下的性
  • 4个强大JavaScript运算符

    作者 Anthony Jimenez 译者 吴留坡 策划 田晓旭 来源 前端之巅 今天我们学习新的 JS 运算符 xff01 你有没有花一个下午的时间阅读 Mozilla 文档 xff1f 如果有 xff0c 你会发现网上有很多 JS 资料