运算符与表达式

JavaScript 运算符是构建表达式的基础组件,根据功能可分为算术、关系、逻辑等多种类型。ECMAScript 标准定义了完整的运算符体系,包括算术操作符(+、-、*、/、%、**)、关系操作符(>、<、>=、<=、==、!=、===、!==)、位操作符(&、|、^ 等)及逻辑操作符(&&、||、!)等核心类别,这些运算符通过组合可形成复杂的表达式,实现数据计算与逻辑判断[3]。

购物车价格计算实践

在电商场景中,运算符的合理应用可显著提升代码效率。以购物车价格计算为例,需综合运用复合赋值、比较运算符及可选链等特性:

复合赋值运算符(+=) 常用于累计计算,通过 total += price * quantity 可简化传统的 total = total + price * quantity 写法,减少变量重复引用。例如:

javascript
复制代码
let total = 0;
const cart = [
  { id: 1, name: "无线耳机", price: 899, quantity: 1 },
  { id: 2, name: "笔记本支架", price: 59, quantity: 2 }
];
for (const item of cart) {
  total += item.price * item.quantity; // 等价于 total = total + (item.price * item.quantity)
}
console.log(total); // 1017

比较运算符 中,===(严格相等)与 ==(宽松相等)的区别是易错点。== 会进行类型转换后比较(如 5 == "5" 结果为 true),而 === 需类型与值完全一致(如 5 === "5" 结果为 false)。在购物车商品ID校验场景中,需使用 === 避免类型转换导致的误判:

javascript
复制代码
function isTargetProduct(productId) {
  const targetId = "10086"; // 后端返回字符串类型ID
  return productId === targetId; // 严格比较类型与值
}
console.log(isTargetProduct(10086)); // false(类型不匹配)
console.log(isTargetProduct("10086")); // true(类型与值均匹配)

可选链运算符(?.) 解决了嵌套对象访问的安全问题。当用户数据结构不确定时(如部分用户未填写地址),user?.address?.city 会在链式访问中遇到 null/undefined 时自动返回 undefined,避免传统写法中 user.address.cityaddress 不存在导致的 TypeError

javascript
复制代码
const user1 = { name: "张三", address: { city: "北京" } };
const user2 = { name: "李四" }; // 无address属性

console.log(user1?.address?.city); // "北京"(正常访问)
console.log(user2?.address?.city); // undefined(安全返回,无报错)

配置参数合并策略

在应用配置场景中,空值合并运算符(??) 与逻辑赋值运算符(??=)可优化默认值设置逻辑,解决传统 || 运算符的缺陷。

传统 || 运算符会将 0、'' 等假值视为无效值,导致合法配置被错误覆盖。例如某配置项允许 timeout: 0(表示无延迟),使用 || 会错误替换为默认值:

javascript
复制代码
// 传统||的缺陷:0被误判为"无效值"
const config = { timeout: 0 }; 
const safeTimeout = config.timeout || 3000; // 3000(错误覆盖0)

空值合并运算符(??) 仅在左侧为 null/undefined 时启用默认值,完美保留 0、'' 等合法假值:

javascript
复制代码
// 使用??修复假值误判问题
const safeTimeout = config.timeout ?? 3000; // 0(正确保留原值)
const apiUrl = config.apiUrl ?? "https://api.default.com"; // 当apiUrl为undefined时使用默认值

逻辑赋值运算符(??=) 进一步简化"空值检测+赋值"逻辑,config.key ??= value 等价于 if (config.key === null || config.key === undefined) config.key = value

javascript
复制代码
// 合并默认配置与用户配置
const defaultConfig = { theme: "light", layout: "grid" };
const userConfig = { theme: "dark" };

// 仅当userConfig中不存在对应属性时应用默认值
userConfig.theme ??= defaultConfig.theme; // "dark"(用户已配置,不覆盖)
userConfig.layout ??= defaultConfig.layout; // "grid"(用户未配置,应用默认)

表达式书写规范

  1. 优先使用严格比较:除明确需要类型转换的场景外,始终用 === 替代 ==,避免隐蔽的类型转换错误。
  2. 安全访问嵌套对象:访问多层属性时强制使用 ?.,尤其处理后端返回的不确定数据结构。
  3. 默认值设置选??:配置项、函数参数等场景中,用 ?? 替代 || 保留合法假值,用 ??= 简化空值赋值逻辑。

通过运算符的场景化应用,可显著提升代码的可读性与健壮性。在实际开发中,需根据具体业务场景选择合适的运算符组合,同时遵循表达式书写规范,降低维护成本。