JavaScript 中的 ??= 运算符:简化变量赋值

在使用 JavaScript 的时候,经常需要对变量进行条件赋值,即只有当变量未定义或为 null 时,才给它赋一个默认值。这种场景在处理对象属性、函数参数等方面尤为常见。JavaScript ES2021 引入的逻辑空赋值运算符(??=)正是为了简化这种操作。本文将探讨 ??= 运算符的使用场景和优势。

理解 ??= 运算符

逻辑空赋值运算符 ??= 是逻辑空合并运算符(??)的赋值版本。它的作用是当变量当前为 nullundefined 时,将其赋值为右侧的值。如果变量已有非 nullundefined 的值,则保持当前值不变。

其基本语法如下:

javascript 复制代码
variable ??= value;

这等价于以下形式

javascript 复制代码
if (variable === null || variable === undefined) {
  variable = value;
}

示例:使用 ??= 运算符初始化对象属性

假设有一个对象 _params,包含了一些配置参数。因为此对象要被序列化成http的query部分;因此需要确保每个参数都有一个有效的值,以防止在后端查询数据库的时候因为 "undefined""null" 引起错误。这时,??= 运算符就能派上用场了。

做如下处理:

javascript 复制代码
const _params = {
  name: "John",
  age: null,
  gender: undefined,
  email: "john@example.com"
};

Object.keys(_params).forEach(key => {
  _params[key] ??= '';
});

const queryParams = new URLSearchParams(_params).toString();
let target = baseUrl;
if (queryParams) {
  target = baseUrl.concat('?').concat(queryParams);
}

上述代码遍历 _params 对象的所有属性。对于每个属性使用 ??= 运算符检查其值是否为 nullundefined。如果是,将其赋值为空字符串 ''。这样,无论 agegender 原本的值如何,执行完这段代码后,它们都会被初始化为一个明确的空字符串,从而避免了在使用这些属性时可能遇到的问题。

使用场景

??= 运算符在日常开发中有多种使用场景:

1. 默认参数赋值

在函数中可以使用 ??= 来为可能未传入的参数提供默认值:

javascript 复制代码
function greet(name) {
  name ??= 'Guest';
  console.log(`Hello, ${name}!`);
}

2. 配置对象的默认属性

在处理配置对象时,??= 运算符非常有用,特别是需要确保对象中的每个属性都有默认值时。这在初始化应用设置或配置时尤为重要,可以避免后续的逻辑错误。

假设有一个表示应用配置的对象,我们希望确保该对象中的某些属性,如果未显式设置,则应赋予它们默认值:

javascript 复制代码
let appConfig = {
  theme: 'dark',
  notifications: undefined,
  fontSize: null
};

// 确保所有配置项都有默认值
appConfig.theme ??= 'light'; // 已经有值,所以保持不变
appConfig.notifications ??= true; // 之前是 undefined,现在赋值为 true
appConfig.fontSize ??= 14; // 之前是 null,现在赋值为 14

console.log(appConfig);
// 输出:{ theme: 'dark', notifications: true, fontSize: 14 }

在这个示例中,theme 属性已经设置了值,因此 ??= 运算符不会改变它。而 notificationsfontSize 属性因为原来的值为 undefinednull,所以被赋予了新的默认值。

3. 状态管理

在前端框架中管理应用状态时,经常需要根据当前状态来更新或赋值新的状态。??= 运算符在这里同样适用,可以用来简化代码,避免不必要的判断逻辑。

例如某个 React 组件中需要根据用户的操作更新组件的状态:

javascript 复制代码
import React, { useState } from 'react';

function UserProfile() {
  const [userProfile, setUserProfile] = useState({
    name: undefined,
    age: null,
    bio: 'No bio provided.'
  });

  // 模拟用户更新操作
const updateUserProfile = (name, age) => {
  setUserProfile(prevState => {
    const newState = {
      ...prevState,
      name,
      age,
    }
    newState.name ??= 'Anonymous';
    newState.age ??= 18;
  });
};

  return (
    <div>
      <button onClick={updateUserProfile}>Update Profile</button>
      <p>Name: {userProfile.name}</p>
      <p>Age: {userProfile.age}</p>
      <p>Bio: {userProfile.bio}</p>
    </div>
  );
}

使用 ??= 运算符来为 nameage 状态提供默认值,当用户点击更新按钮而这些状态未被定义时。如此一来,可以确保 userProfile 状态始终保持完整和一致,而不需要编写复杂的逻辑来检查每个值是否存在。

结论

??= 运算符是 JavaScript 中的一个实用的新特性,它提供了一种简洁明了的方式来对变量进行空值检查和赋值操作。通过使用 ??=,开发者可以减少代码的冗余,提高代码的可读性和健壮性。在日常开发中合理利用这一特性,可以有效地避免 nullundefined 值带来的问题,保证数据的完整性和程序的稳定性。

相关推荐
王哲晓12 分钟前
第三十章 章节练习商品列表组件封装
前端·javascript·vue.js
理想不理想v17 分钟前
‌Vue 3相比Vue 2的主要改进‌?
前端·javascript·vue.js·面试
酷酷的阿云27 分钟前
不用ECharts!从0到1徒手撸一个Vue3柱状图
前端·javascript·vue.js
aPurpleBerry1 小时前
JS常用数组方法 reduce filter find forEach
javascript
ZL不懂前端2 小时前
Content Security Policy (CSP)
前端·javascript·面试
乐闻x2 小时前
ESLint 使用教程(一):从零配置 ESLint
javascript·eslint
我血条子呢3 小时前
[Vue]防止路由重复跳转
前端·javascript·vue.js
半开半落3 小时前
nuxt3安装pinia报错500[vite-node] [ERR_LOAD_URL]问题解决
前端·javascript·vue.js·nuxt
理想不理想v3 小时前
vue经典前端面试题
前端·javascript·vue.js