【08】ES6:运算符的扩展

一、指数运算符

指数运算符(**)返回第一个操作数取第二个操作数的幂的结果。

x ** y2 ** 2 // 4
2 ** 3 // 8

指数运算符是右结合的。

a ** b ** c 等于 a ** (b ** c)2 ** 3 ** 2  // 相当于 2 ** (3 ** 2)  512

指数运算符可以与等号结合,形成一个新的赋值运算符(**=)。

let a = 1.5
a **= 2 // 等同于 a = a * alet b = 4
b **= 3 // 等同于 b = b * b * b;

二、链判断运算符

链判断运算符(可选链运算符)?. 允许读取位于连接对象链深处的属性的值,而不必明确验证链中的每个引用是否有效。

?. 运算符的功能类似于 . 链式运算符,不同之处在于,在引用为空的情况下不会引起错误,而是返回 undefined。(在链式调用的时候判断,左侧的对象是否为 null 或 undefined,如果是的,就不再往下运算,而是返回 undefined。)

// 错误的写法
const  firstName = message.body.user.firstName || 'default'// && 运算符
const firstName = (message&& message.body&& message.body.user&& message.body.user.firstName) || 'default'// ?: 三元运算符
const fooInput = myForm.querySelector('input[name=foo]')
const fooValue = fooInput ? fooInput.value : undefined// .? 可选链运算符
const firstName = message?.body?.user?.firstName || 'default'
const fooValue = myForm.querySelector('input[name=foo]')?.value

链判断运算符 ?. 有三种写法

  • obj?.prop // 对象属性是否存在
  • obj?.[expr] // 同上
  • func?.(…args) // 函数或对象方法是否存在
// obj?.[expr] 用法:没有发现匹配返回 null,发现匹配返回一个数组
let hex = '#C0FFEE'.match(/#([A-Z]+)/i)?.[1]a?.b
// 等同于
a == null ? undefined : a.ba?.[x]
// 等同于
a == null ? undefined : a[x]a?.b()
// 等同于(如果 a?.b() 里面的 a.b 有值,但不是函数,不可调用,那么 a?.b() 是会报错的。)
a == null ? undefined : a.b()a?.()
// 等同于(如果 a 不是 null 或 undefined ,但也不是函数,那么 a?.() 会报错。)
a == null ? undefined : a()

注意点

(1)短路机制

本质上,?. 运算符相当于一种短路机制,只要不满足条件,就不再往下执行。

a?.[++x]
// 等同于
a == null ? undefined : a[++x]

上面代码中,如果 a 是 undefined 或 null ,那么 x 不会进行递增运算。也就是说,链判断运算符一旦为真,右侧的表达式就不再求值。

(2)括号的影响

如果属性链有圆括号,链判断运算符对圆括号外部没有影响,只对圆括号内部有影响。

(a?.b).c
// 等价于
(a == null ? undefined : a.b).c

上面代码中,?. 对圆括号外部没有影响,不管 a 对象是否存在,圆括号后面的 .c 总是会执行。

一般来说,使用 ?. 运算符的场合,不应该使用圆括号。

(3)报错场合

以下写法是禁止的,会报错。

// 构造函数
new a?.()
new a?.b()// 链判断运算符的右侧有模板字符串
a?.`{b}`
a?.b`{c}`// 链判断运算符的左侧是 super
super?.()
super?.foo// 链运算符用于赋值运算符左侧
a?.b = c

(4)右侧不得为十进制数值

为了保证兼容以前的代码,允许 foo?.3:0 被解析成 foo ? .3 : 0,因此规定如果 ?. 后面紧跟一个十进制数字,那么 ?. 不再被看成是一个完整的运算符,而会按照三元运算符进行处理,也就是说,那个小数点会归属于后面的十进制数字,形成一个小数。

三、Null 判断运算符

Null 判断运算符 ??,又称空值合并运算符。是一个逻辑运算符,当左侧的操作数为 null 或者 undefined 时,返回其右侧操作数,否则返回左侧操作数。

语法

leftExpr ?? rightExpr
const nullValue = null
const emptyText = '' // 空字符串,是一个假值,Boolean('') === false
const someNumber = 42const valA = nullValue ?? 'valA 的默认值'
// valA 的默认值
const valB = emptyText ?? 'valB 的默认值'
// ''(空字符串虽然是假值,但不是 null 或者 undefined)
const valC = someNumber ?? 0
// 42

常见用途

(1)为变量赋默认值

读取对象属性的时候,如果某个属性的值是 null 或 undefined,有时候需要为它们指定默认值。常见做法是通过 || 运算符指定默认值。

逻辑或运算符会在左侧操作数为假值时返回右侧操作数。也就是说,如果使用 || 来为某些变量设置默认值,可能会遇到意料之外的行为。比如为假值(例如,‘’ 或 0 或 false)时。

使用空值合并运算符 ??可以避免这种情况,只有运算符左侧的值为 null 或 undefined 时,才会返回右侧的值。

let myText = '' // An empty string (which is also a falsy value)let notFalsyText = myText || 'Hello world'
console.log(notFalsyText) // Hello worldlet preservingFalsy = myText ?? 'Hi neighborhood'
console.log(preservingFalsy); // '' (as myText is neither undefined nor null)

(2)与链判断运算符 ?. 配合使用为 null 或 undefined 的值设置默认值。

const animationDuration = response.settings?.animationDuration ?? 300

上面代码中,如果 response.settings 是 null 或 undefined ,或者 response.settings.animationDuration 是 null 或 undefined ,就会返回默认值 300。也就是说,这一行代码包括了两级属性的判断。

注意点

(1)短路机制

ORAND 逻辑运算符相似,当左表达式不为 null 或 undefined 时,不会对右表达式进行求值。

function A() {console.log('函数 A 被调用了')return undefined
}
function B() {console.log('函数 B 被调用了')return false
}
function C() {console.log('函数 C 被调用了')return 'foo'
}console.log(A() ?? C())
// 依次打印 '函数 A 被调用了'、'函数 C 被调用了'、'foo'
// A() 返回了 undefined,所以运算符两边的表达式都被执行了console.log(B() ?? C())
// 依次打印 '函数 B 被调用了'、'false'
// B() 返回了 false(既不是 null 也不是 undefined)
// 所以右侧表达式没有被执行

(2)优先级问题

?? 运算符 和其他逻辑运算符 &&|| 之间的运算优先级/运算顺序是未定义的,组合使用时,必须用括号表明优先级,否则会报错。

null || undefined ?? 'foo' // 抛出 SyntaxError
true || undefined ?? 'foo' // 抛出 SyntaxError(null || undefined) ?? 'foo' // 返回 'foo'

四、逻辑赋值运算符

ES2021 引入了三个新的逻辑赋值运算符(logical assignment operators),将逻辑运算符与赋值运算符进行结合。

逻辑赋值运算符说明
||=逻辑或赋值运算符(x ||= y)运算仅在 x 为假值时为其赋值。等同于 x || (x = y)。
&&=逻辑与赋值运算符(x &&= y)运算仅在 x 为真值时为其赋值。等同于 x && (x = y)。
??=逻辑空赋值运算符(x ??= y)仅在 x 是空值(null 或 undefined)时对其赋值。等同于 x ?? (x = y)。

这三个运算符 ||=&&=??= 相当于先进行逻辑运算,然后根据运算结果,再视情况进行赋值运算。

用途:为变量或属性设置默认值。

user.id 属性如果不存在,则设为 1,新的写法比老的写法更紧凑一些。

// 老的写法
user.id = user.id || 1// 新的写法
user.id ||= 1

参数对象 opts 如果不存在属性 foo 和属性 baz,则为这两个属性设置默认值。

function example(opts) {opts.foo = opts.foo ?? 'bar'opts.baz ?? (opts.baz = 'qux')
}function example(opts) {opts.foo ??= 'bar'opts.baz ??= 'qux'
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/220147.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

数据结构和算法 - 前置扫盲

数据结构和算法 一、前置扫盲 1、数据结构分类 1.1 逻辑结构:线性与非线性 tip:逻辑结构揭示了数据元素之间的逻辑关系。 线性数据结构:元素间存在明确的顺序关系。 数据按照一定顺序排列,其中元素之间存在一个对应关系&#x…

独立完成软件的功能的测试(5. 完结总结)

独立完成软件的功能的测试(5. 完结&总结) 软件测试的基础理论 1. 什么是软件:控制计算机硬件的工具。2. 什么是软件测试:使用技术的手段,查找软件的缺陷,保证软件的质量3. 软件测试的分类1. 阶段分&am…

Liunx系统挂载磁盘

1.具体步骤 大概五个步骤 添加磁盘磁盘分区格式化分区挂载分区到指定目录设置开机自动挂载 目标将sdb1分区挂载到/data目录 2.添加磁盘 使用lsblk -f命令可以查看当前系统磁盘情况 lsblk -f 可以看到已经有一个磁盘sda,现在我们给虚拟机增加一个磁盘 添加完成后…

数据结构-集合

介绍 数据结构中的集合是一种包含不同元素的数据结构,其中每个元素都是独一无二的,即集合中的元素互不相同且无序。 集合数据结构分类如下: 并集是两个集合的所有部分合并在一起形成的集合;交集是两个集合共同包含的元素组成的集…

数据结构与算法:插入排序

原理 保证区间内排好顺序,逐渐将区间外数据插入到该区间中。 从局部扩散到整体。 第一次:保证0-1范围内有序 arr[0]和arr[1]对比,若arr[0] 大于 arr[1] ,交换两个值, 0-1范围内有序。 第二次:保证 0-2 …

Java八股文面试全套真题【含答案】- Spring篇

以下是一些关于Spring的经典面试题以及它们的答案: 什么是Spring框架? Spring是一个轻量级的开源Java框架,用于快速构建企业级应用程序。它提供了一个容器,可以集中管理和组织应用程序的各个组件,同时提供了一套丰富的…

记录 | 命令行模式clash报错Can‘t find MMDB, start download

下载: https://link.zhihu.com/?targethttps%3A//gitee.com/mirrors/Pingtunnel/blob/master/GeoLite2-Country.mmdb 重命名为 Country.mmdb 下载完放到 ./clash 启动的同级目录就行 不行的话就放到 ~/.config/clash 下

【PID学习笔记 8 】控制系统的分析方法之一

写在前面 前面已经完成了控制系统的性能指标学习,从这节开始继续学习控制系统的分析方法,本文重点介绍分析方法概述和时域分析法。 一、控制系统的基本分析方法 控制系统的基本分析方法包括: 古典方法(经典控制理论)…

力扣题:数字与字符串间转换-12.14

力扣题-12.14 [力扣刷题攻略] Re:从零开始的力扣刷题生活 力扣题1:442. 数组中重复的数据 解题思想:从字符串中能够正确提取数字即可 class Solution(object):def complexNumberMultiply(self, num1, num2):""":type num1:…

nextTick详解

一. nextTick是什么? 官方定义: 在下次DOM更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法,获取更新后的DOM翻译一下就是: Vue在更新DOM时是异步执行的。当数据发生变化的时候,Vue将开启队列&#xf…

2.5 常规游戏中模型通用要求介绍

一、布线和理性 多星点(4个及4个以上边的交点) 如果是在中模阶段,减少使用多星点,因为会在细分是时出现凸点问题,如果要使用多星点,需要通过布线技巧把它移动至平面处,不要让他出现在倒角边缘。…

科技提升安全,基于DETR【DEtection TRansformer】模型开发构建商超扶梯场景下行人安全行为姿态检测识别系统

在商超等人流量较为密集的场景下经常会报道出现一些行人在扶梯上摔倒、受伤等问题,随着AI技术的快速发展与不断普及,越来越多的商超、地铁等场景开始加装专用的安全检测预警系统,核心工作原理即使AI模型与摄像头图像视频流的实时计算&#xf…

深入理解Java虚拟机---Java内存模型

JMM Java内存模型主内存和工作内存volatile Java内存模型 Java内存模型是Java虚拟机规范中试图定义一种Java内存模型(JMM)来屏蔽掉各种硬件和操作系统的内存访问差异,以实现让Java程序在各种平台上都能达到一致的内存访问效果。可以理解为JMM定义一套在多线程读写共…

Linux常见排错思路及命令

Linux常见排错思路及命令 一、引言 在Linux系统中,由于其高度可配置和可定制的特性,可能会遇到各种问题。本文将介绍一些常见的排错思路,并提供一些常用的命令,以帮助您快速定位和解决问题。 二、常见排错思路 查看系统日志 …

计算机网络简答题

面向连接和非连接的服务特点 面向连接的服务:通信双方在进行通信之前,要事先建立一个完整的可以彼此沟通的通道,在通信过程中整个连接的情况可以被实时的监控和管理 面向非链接的服务:不需要预先建立一个联络两个通信节点的连接&a…

智能优化算法应用:基于平衡优化器算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用:基于平衡优化器算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用:基于平衡优化器算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.平衡优化器算法4.实验参数设定5.算法…

每日一题:Leetcode1926.迷宫中离入口最近的出口

给你一个 m x n 的迷宫矩阵 maze (下标从 0 开始),矩阵中有空格子(用 . 表示)和墙(用 表示)。同时给你迷宫的入口 entrance ,用 entrance [entrancerow, entrancecol] 表示你一开始…

HBase 高可用集群详细图文安装部署

目录 一、HBase 安装部署 1.1 Zookeeper 正常部署 1.2 Hadoop 正常部署 1.3 HBase 安装 1.4 HBase 的配置文件 1.4.1 hbase-env.sh 1.4.2 hbase-site.xml 1.4.3 regionservers 1.4.4 创建目录 1.5 HBase 远程发送到其他节点 1.6 HBase 服务的启动 1.6.1 单点…

分类预测 | Matlab实现HPO-GRU【23年新算法】基于猎食者优化算法优化门控循环单元的数据分类预测

分类预测 | Matlab实现DBO-SVM蜣螂算法优化支持向量机的数据分类预测【23年新算法】 目录 分类预测 | Matlab实现DBO-SVM蜣螂算法优化支持向量机的数据分类预测【23年新算法】分类效果基本描述程序设计参考资料 分类效果 基本描述 1.HPO-GRU【23年新算法】基于猎食者优化算法优…

【电子取证:FTK IMAGER 篇】DD、E01系统镜像动态仿真

​ 文章目录 【电子取证:FTK Imager 篇】DD、E01系统镜像动态仿真一、DD、E01系统镜像动态仿真 (一)使用到的软件 1、FTK Imager (v4.5.0.3)2、VMware Workstation 15 Pro (v15.5.2)(二)FTK Imager 挂载镜像 1、选择 …