JS 中一些高效的魔法运算符
这两天有同事说我挺久没更新文章了,不过最近一段时间确实有点忙,一直在忙着两个活动中心的改版,没什么时间来更新文章。今天终于抽空可以写一写。

JavaScript 现在每年都会发一个新版本,里面也会新增一些操作更加便利、高效的运算符。今天我们就来盘点下几个高效的魔法运算符。
1. 可选链运算符
之前当我们想要使用某个结构比较深的属性,同时又无法确定所有的父级一定存在时,我们需要进行一连串的判断,例如一个数据结构:
const student = {
score: {
math: 98,
},
};
我们想要获取最内层的 math 属性的值时:
if (student && student.score) {
console.log(student.score.math);
}
1.1 获取深层次的属性
不过当我们使用可选链运算符后,判断就简单很多了,可选链运算符会在链路上遇到 null 或者 undefined 时,直接返回 undefined,而不会抛出错误异常:
console.log(student?.score?.math);
1.2 执行一个可选的方法
同时在执行一个可能存在的函数时,也可以用到。例如一个 react 组件中,传入的方法是可选的:
// getScore 是一个可选参数,要么是 undefined,要么是一个函数
const Student = ({ getScore }: { getScore?: () => void }) => {
useEffect(() => {
// 当 getScore 存在时,正常执行 getScore()方法
getScore?.();
}, []);
return <div></div>;
};
或者我们执行一个 dom 元素的方法时,也可以使用。
document.querySelector 会返回两种类型,当 dom 元素真实存在时会返回该元素,否则返回 null。写过 typescript 的都知道,当我们要调用某个方法时,总是要先确定该 dom 元素是存在的:
const dom = document.querySelector('.score');
if (dom) {
dom.getBoundingClientRect(); // 当 dom 元素存在时,才执行该方法
}
使用可选链操作符时,就直接调用即可:
document.querySelector('.score')?.getBoundingClientRect();
1.3 获取数组中的值
若数组存在,则获取某个下标的值,我们现在也不用再判断数组是否存在了,可以直接使用:
arr?.[1]; // 若 arr 存在时,则正常获取 arr[1]中的值
上面的 3 种情况也是可以组合使用的。若一个结构比较复杂时,各种类型都有,这里我们要执行数组 math 下标 2 的方法:
const student = {
score: {
math: [
98,
67,
() => {
return 99;
},
],
},
};
执行:
student?.score?.math?.[2]?.(); // 99

1.4 无法进行赋值操作
可选链运算符只能执行获取操作,是无法进行赋值操作的。
例如给一个可能的数组或者 dom 元素赋值时,会直接抛出语法异常:
arr?.[1] = 2; // x
document.querySelector('.score')?.innerHTML = 98; // x
当我们执行上面的语句时,会抛出如下的提示:
Uncaught SyntaxError: Invalid left-hand side in assignment
即不能给左侧的可选链进行赋值操作。
2. 双问号运算符
双问号运算符??,我理解是为了解决或运算符||而设计出来的。
我们先来回顾下或运算符的操作,当左侧的数据为假值(数字 0, 布尔类型的 false,空字符串,undefined, null)时,则执行右侧的语句。
false || 123;
0 || 123;
'' || '123';
undefined || 123;
null || 123;
可是在有些情况下,false 和 0 都是正常的值,但若使用或运算符时,会导致出错。
比如下面的这个例子,当 score 为空时,则默认值为 1。当输入正常值 0 时应当返回 0(但实际上返回了 1):
const getSCore = (score: number) => {
return score || 1;
};
getScore(0); // 1
这时,我们就用到了双问号运算符??。双问号运算符只会在左侧为 undefined 或者 null 时,才会执行右侧的语句。
const getSCore = (score: number) => {
return score ?? 1;
};
getScore(0); // 0
同时,双问号运算符还可以与=结合成为一个赋值操作,当左侧为 null 或者 undefined 时,则将右侧语句的结果赋值给左侧的变量:
score ??= 1; // 1

3. 或运算和与运算的赋值操作
我们在之前使用或运算符进行赋值操作时,是这样写的:
score = score || 1;
age = age && 24;
现在可以直接简写成:
score ||= 1; // 等同于 score = score || 1
age &&= 24; // 等同于 age = age && 24
4. 双星号运算符
双星号运算符**是比较早引入到 js 中的,只是我们用到的比较少而已。其实它执行的是一个幂运算,等同于 Math.pow()。
2 ** 10; // 1024, 2的10次方,等同于 Math.pow(2, 10);
5. 总结
以上所有的样例均已在 chrome90 上运行通过。

我们在已经有 babel 帮助转换的情况下,可以适当的在代码运用这些运算符,能够极大地简化我们的代码。
也欢迎您关注我的公众号:“前端小茶馆”

JS 中一些高效的魔法运算符的更多相关文章
- JavaScript基础&实战(2)js中的强制类型转换、运算符、关系运算符、逻辑运算符、条件运算符
文章目录 1.强制类型转换Number 1.1 代码 1.2 测试结果 2.进制表示 2.1 代码 2.2 测试结果 3.强制类型转换为Boolea 3.1 代码 3.2 测试结果 4.运算符 4.1 ...
- JS中的 && 、|| 、??、?. 运算符
javascript有不少好用的运算符,合理的使用可以大大提高工作效率,以下简单介绍了4种,具体如下: && 逻辑与运算(&&)是 AND 布尔操作.只有两个操作数都为 ...
- js中的相等与逗号运算符用法
/** * 相等运算符 '==',相等则返回true,不等则返回false * - 用 '==' 来比较两个值时,若值的类型不同,则会自动进行类型 * 转换,将其转换为相同的类型然后再进行比较. */ ...
- JS中的分支结构
if语句 语法: if (expression1) { } else if (expression2) { } else { } 执行机制: 先对expression1做判定,如果为真,执行对应的代码 ...
- js中的等值运算符(抽象相等==与严格相等===的区别)
js中的等值运算符 js中的相等分为抽象相等和严格相等,他们有什么区别呢. 在说具体算法前,先提下JS数据类型,JS数据类型分为6类:Undefined Null String Number Bool ...
- js中的运算符优先级顺序
js中运算符优先级从高到底的顺序: 算术操作符 → 比较操作符 → 逻辑操作符 → "="赋值符号
- js中的运算符和条件语句
js中的运算符大体上可以分为4类:1算术运算符.2一元操作符.3比较运算符.4逻辑运算符. 算术运算符一般指的是加减乘除求余这五种操作符:+,-,*,/,%.通过算术运算符可以对js中的变量进行操作. ...
- Javascript开发技巧(JS中的变量、运算符、分支结构、循环结构)
一.Js简介和入门 继续跟进JS开发的相关教程. <!-- [使用JS的三种方式] 1.HTML标签中内嵌JS(不提倡使用): 示例:<button onclick="javas ...
- JavaScript 基础——使用js的三种方式,js中的变量,js中的输出语句,js中的运算符;js中的分支结构
JavaScript 1.是什么:基于浏览器 基于(面向)对象 事件驱动 脚本语言 2.作用:表单验证,减轻服务器压力 添加野面动画效果 动态更改页面内容 Ajax网络请求 () 3.组成部分:ECM ...
随机推荐
- 从零开始使用 webpack5 搭建 react 项目
本文的示例项目源码可以点击 这里 获取 一.前言 webpack5 也已经发布一段时间了,其模块联邦.bundle 缓存等新特性值得在项目中进行使用.经过笔者在公司实际项目中的升级结果来看,其提升效果 ...
- JAVA网络编程基本功之Servlet与Servlet容器
Servlet与Servlet容器关系 Servlet 比较这两个的区别, 就得先搞清楚Servlet 的含义, Servlet (/ˈsərvlit/ ) 翻译成中文就是小型应用程序或者小服务程序, ...
- XXL-JOB v2.3.0 发布 | 易用性增强
转: XXL-JOB v2.3.0 发布 | 易用性增强 v2.3.0 Release Notes 1.[新增]调度过期策略:调度中心错过调度时间的补偿处理策略,包括:忽略.立即补偿触发一次等: 2. ...
- c++函数指针说明
下面随笔说明函数指针用法. 函数指针的定义: 定义形式: 存储类型 数据类型 (*函数指针名)() 含义: 函数指针指向的是程序代码存储区 函数指针的典型用途-----实现函数回调 通过函数指针调用的 ...
- Java-Socket通信 知识点记录
目录 一.Socket基本案例 二.消息通信 2.1 双向通信 2.2 告知发送结束 2.2.1 通过Socket关闭 2.2.2 通过Socket关闭输出流的方式 2.2.3 通过约定符号 2.2. ...
- python带颜色打印字符串
python带颜色打印字符串 之前调试pwn题的时候,有时候需要将某些特别的,重要的信息用不一样的颜色打印出来.查阅一些资料,了解了print函数的特性后,自己写了一个脚本,可以用来获取带颜色信息的字 ...
- ES系列(一):编译准备与server启动过程解析
ES作为强大的和流行的搜索引擎服务组件,为我们提供了方便的和高性能的搜索服务.在实际应用中也是用得比较爽,但如果能够更深入一点.虽然网上有许多的文章已经完整说明,ES是如何如何做到高性能,如何做到高可 ...
- Java 集合框架体系总览
尽人事,听天命.博主东南大学硕士在读,热爱健身和篮球,乐于分享技术相关的所见所得,关注公众号 @ 飞天小牛肉,第一时间获取文章更新,成长的路上我们一起进步 本文已收录于 「CS-Wiki」Gitee ...
- 题解 洛谷P1990 覆盖墙壁
DP康复训练题 原题:洛谷P1990 核心:递推/DP 题源应该是铺地砖,所以采用一摸一样的思路,只是有两种不同的方块 我们先用最最简单的方式尝试一下枚举当最后一行被填满的情况: 1.如果我们只用第一 ...
- ES6学习笔记(4)- 解构
一.解构的意义 二.对象解构 三.数组解构