Hey,前端小伙伴们!我是老王。最近需要写一个简单的SDK,因为涉及到三方交互,返回类型的不确定性很高,所以对属性方法是否存在一通判断,代码极其不优雅,最后只能用TypeScript进行强类型约束了。
今天咱们来聊聊那些让JavaScript代码变得更加简洁、高效的新运算符。随着ECMAScript的不断更新,我们的代码库也得焕发一波生机了。
Null判断运算符(??)
ES2020的实用派------Null判断运算符??
。专门用来处理默认值的赋值问题。
Null判断运算符??
提供了一种更精确的方法来为变量指定默认值。它只有在左侧的值为null
或undefined
时,才会将右侧的值赋给左侧的变量。
javascript
// 假设我们有一个配置对象
const config = {
apiUrl: 'https://api.example.com'
};
// 旧方法设置默认值
const defaultApiUrl = config.apiUrl || 'https://default.api.com';
// 设置一个默认值,但只有当config.apiUrl是null或undefined时
// ES2020之后
// 使用Null判断运算符??
const defaultApiUrl = config.apiUrl ?? 'https://default.api.com';
我们通常使用||
运算符来为变量指定默认值。但是,这会导致空字符串、false
或0
也被替换为默认值。
这样一来,我们就不用担心因为这些假值(比如0
或""
)而意外地覆盖了预期的行为。
可选链运算符(?.)
我猜大多数的开发者都是用过这个运算符。在处理深层嵌套的对象属性时,我们需要确保每一级对象都存在,否则可能会抛出错误。链判断运算符让访问深层嵌套对象属性时的判断变得无比优雅。
javascript
// 想象一下,我们有一个用户对象,多层嵌套
const user = {
info: {
name: 'Alice'
}
};
// 旧的方式,我们需要层层检查
const userName = user && user.info && user.info.name;
// 现在,使用?.运算符,一切变得简单
const userName = user?.info?.name;
这不仅仅是代码量的减少,更是逻辑清晰度的提升!
本质上,?.
运算符相当于一种短路机制,只要不满足条件,就不再往下执行。
javascript
user?.[++x]
// 等同于
user == null ? undefined : a[++x]
如果user
是undefined
或null
,那么x
不会进行递增运算。也就是说,链判断运算符一旦为真,右侧的表达式就不再求值。虽然递增运算的优先级高于可选链运算符。
逻辑赋值运算符
让我们看看ES2021带来的逻辑赋值运算符。这三位小伙伴||=
、&&=
和??=
将逻辑运算和赋值结合在一起,让我们的代码更加紧凑。
javascript
// 逻辑或赋值运算符 ||=
let highScore = 0;
const playerScore = 2300;
// 如果highScore太低,就更新它
highScore ||= playerScore;
// 与赋值运算符 &&=
const isVerified = false;
const verifiedStatus = isVerified || 'pending';
// 更新verifiedStatus,但只有当isVerified为假值时
isVerified &&= 'verified';
// Null赋值运算符 ??=
const userPreferences = {
theme: null
};
// 如果theme没有设置,就给它一个默认值
userPreferences.theme ??= 'light';
这些运算符不仅节省了代码空间,更重要的是,它们让代码的意图更加明确。
指数运算符(**)
在ES6之前,JavaScript并没有专门的指数运算符。我们通常需要使用Math.pow(base, exponent)
来计算幂。但是,从ES2016开始,我们可以直接使用**
作为指数运算符。
javascript
// ES6之前
Math.pow(2, 3);// 8
// ES6之后
2 ** 3;// 8
值得注意的是,这个运算符是右结合的,意味着多个指数运算符连用时,是从最右边开始计算的。
总结
好啦,希望这篇文章能帮助你更好地理解和使用这些新特性,让我们一起迈向更加优雅的编程之路吧!
From 公众号 <老王聊前端>