☰
jstips 第 35 期:JavaScript 赋值运算符与赋值简写技巧全解析
2026/10/8 17:45:08 网站建设 项目流程
  • 教程

【免费下载链接】jstips

This is about useful JS tips!

项目地址:https://gitcode.com/gh_mirrors/js/jstips
点击查看免费下载

本篇技术指南以 jstips 项目第 35 号 tip(Assignment Operators)为骨架,系统讲解 JavaScript 中各类赋值简写(compound assignment)、++/--前置与后置差异、三元运算符替代 if-else、||默认值赋值、数组与对象字面量声明等实战技巧。读完本文,你将掌握一套"打字更少、语义更清晰"的赋值写法,并理解每种简写背后的求值顺序与陷阱,可直接应用于日常业务代码与代码评审。

为什么要写赋值简写

赋值(Assignment)是 JavaScript 中出现频率最高的操作之一。正如该 tip 作者 hsleonis 所说:对于"懒惰的程序员"而言,反复敲击冗长的赋值语句非常耗时,而使用简写可以让代码更干净(cleaner)也更简单(simpler)。这类技巧不是炫技,而是通过减少重复、收敛意图,让代码在可读性与可维护性上同时受益。

复合赋值运算符:一张表掌握所有简写

所谓复合赋值(compound assignment),就是把"二元运算 + 赋值"合并成一个运算符。原文档给出了最核心的一组对照,它们语义完全等价于展开写法:

x += 23; // x = x + 23; y -= 15; // y = y - 15; z *= 10; // z = z * 10; k /= 7; // k = k / 7; p %= 3; // p = p % 3; d **= 2; // d = d ** 2; m >>= 2; // m = m >> 2; n <<= 2; // n = n << 2; n++; // n = n + 1; n--; // n = n - 1;

各运算符的语义与适用范围整理如下:

简写等价展开运算类型典型使用场景
+=x = x + y加法/字符串拼接累加器、统计计数、字符串累积
-=x = x - y减法倒计时、步进回退
*=x = x * y乘法缩放、倍增
/=x = x / y除法均分、比例计算
%=x = x % y取模环形索引、奇偶判断
**=x = x ** y幂运算(ES2016)几何增长、单位换算
>>=x = x >> y有符号右移位运算、二分查找中位
<<=x = x << y左移位掩码、快速乘 2 的幂

其中**=(指数赋值)是 ES2016 才引入的运算符,使用时需注意运行环境支持情况(Node.js 7+ 与主流现代浏览器均已支持)。>>=与<<=属于位运算范畴,处理的是 32 位整数语义,业务代码中相对少见,但作为 JS 基础语法值得掌握。

以 Node.js v18 实测验证(与文档示例一致):

var x = 2; x += 23; console.log(x); // 25 var p = 7; p %= 3; console.log(p); // 1 var d = 5; d **= 2; console.log(d); // 25 var m = 8; m >>= 2; console.log(m); // 2 var n = 1; n <<= 2; console.log(n); // 4

++与--:前缀与后缀的本质差异

++是文档专门强调的"特殊运算符",难点在于它既返回值又改变变量。关键差异是求值的先后顺序:

后缀(postfix):先返回,后自增

var a = 2; var b = a++; // 现在 a 是 3,b 是 2

a++语句实际完成两个步骤:

  1. 返回a的当前值;
  2. 将a自增 1。

因此赋值给b的是自增之前的旧值 2,而a本身变为 3。

前缀(prefix):先自增,后返回

var a = 2; var b = ++a; // 现在 a 和 b 都是 3

操作符放在变量前面(++a)时,会先完成自增,再把新值 3 返回并赋给b。

--与++行为完全对称,只是把"自增 1"换成"自减 1"。

实践建议:当自增/自减作为独立语句(如i++单独一行)使用时,前缀与后缀没有区别;一旦参与赋值或表达式求值,就必须明确区分。在for循环、数组遍历等场景中,这往往是隐蔽 bug 的来源,建议在代码评审中重点检查。

用三元运算符压缩 if-else 赋值

日常最常见的赋值分支写法:

var newValue; if (value > 10) newValue = 5; else newValue = 2;

用三元运算符可以压缩为一行,且语义完全等价:

var newValue = (value > 10) ? 5 : 2;

三元运算符的求值规则为:条件 ? 条件为真时的值 : 条件为假时的值。它适合两个分支都只产生一个值的简单场景,能消除临时变量的声明与分支噪声。但需要提醒:当分支内部含有副作用(多次调用、赋值多个变量)或逻辑复杂时,应保留 if-else 以保证可读性——简写的目标是"清晰",而不是"最短"。

||简写:一行完成 null/undefined/空值检查

原文档给出了一个非常典型的赋值场景:

if (variable1 !== null || variable1 !== undefined || variable1 !== '') { var variable2 = variable1; }

简写形式:

var variable2 = variable1 || '';

其底层原理正是短路求值(short-circuit evaluation):当||左侧的操作数能够决定整个表达式的结果时,右侧根本不会被求值。更精确地说,||返回的是第一个真值(truthy)操作数;如果左侧为假值(falsy),则返回右侧操作数。因此variable1 || ''的含义是:variable1为真值时取variable1本身,否则回退到空字符串。关于该机制的完整讲解可参考仓库姊妹篇 Short circuit evaluation in JS,其中还展示了name = name || 'Bar'式的默认参数写法。

这条简写非常实用,但有一个重要边界条件,文档末尾的 P.S. 专门提醒:如果variable1是数字,必须先检查它是否为 0。因为0在 JavaScript 中是假值,0 || ''会得到''而非0,从而破坏原本"保留数值 0"的意图。

要彻底理解这一点,需要掌握 JavaScript 的假值集合:false、0、-0、0n、''、null、undefined、NaN。仓库中的 Converting truthy/falsy values to boolean(!!技巧)和 Differences between undefined and null 对这部分有专门展开。

实测验证:

var variable1 = ''; // 空字符串是假值 var variable2 = variable1 || ''; console.log(variable2); // "" var variable3 = null; console.log(variable3 || 'fallback'); // "fallback" var count = 0; console.log(count || 10); // 10 —— 注意:0 被当作"未提供"处理了

数组字面量:告别new Array()逐项填充

文档对比了两种创建并填充数组的写法。不推荐:

var a = new Array(); a[0] = "myString1"; a[1] = "myString2";

推荐使用数组字面量,一行声明 + 初始化:

var a = ["myString1", "myString2"];

数组字面量[...]的优势:无需构造器调用、天然支持任意长度与嵌套、可读性更强,且避免了new Array(3)这类"传入单个数字会创建稀疏数组"的经典陷阱。

关联数组:用对象字面量替代字符串索引

JavaScript 中并不存在真正的"关联数组",用数组配合字符串键是反模式:

var skillSet = new Array(); skillSet['Document language'] = 'HTML5'; skillSet['Styling language'] = 'CSS3';

正确做法是直接使用对象字面量:

var skillSet = { 'Document language': 'HTML5', 'Styling language': 'CSS3' };

二者的本质区别:数组的索引应当是数字;用字符串索引给数组赋值,实际是在给数组对象动态添加属性,并不会像真正的关联容器那样工作。对象字面量才是"键-值映射"的正确载体,这也与仓库中 Check if a property is in a Object 讨论的in运算符与hasOwnProperty检查互为呼应。

综合实践清单

把本文所有简写整合进一段可运行的示例,便于对照复习:

// 1. 复合赋值 var score = 0; score += 10; // 10 score -= 2; // 8 // 2. 前缀/后缀自增 var i = 0; var j = i++; // j = 0, i = 1 var k = ++i; // k = 2, i = 2 // 3. 三元赋值 var level = (score > 5) ? 'high' : 'low'; // 'high' // 4. || 默认值(注意 0 与 '' 的边界) var userInput = ''; var finalInput = userInput || 'default'; // 'default' // 5. 数组与对象字面量 var tags = ['js', 'tips']; var config = { debug: true, retries: 3 };

延伸阅读

  • 本文依据:Assignment Operators(jstips 第 35 期),仓库内另有简体中文版 _posts/zh_CN/javascript/2016-02-04-assignment-shorthands.md、西班牙语版 _posts/es_ES/javascript/2016-02-04-assignment-shorthands.md 与繁体中文版 _posts/zh_TW/javascript/2016-02-04-assignment-shorthands.md;
  • Short circuit evaluation in JS:||与&&短路求值的完整原理与默认参数实践;
  • Converting truthy/falsy values to boolean:!!双非运算符与真假值速查;
  • Differences between undefined and null:null与undefined的判定差异,辅助理解||回退逻辑;
  • Basics declarations:var声明与链式赋值x = y = 1的作用域细节。

以上代码示例均在 Node.js v18 环境下实际运行验证,结论与文档描述一致。需要注意的是:本文示例沿用原文档的var写法以忠实还原 2016 年语境,现代项目中建议按需升级为let/const(可参考仓库 ES6, var vs let),但运算符本身的求值语义完全不变。

  • 教程

【免费下载链接】jstips

This is about useful JS tips!

项目地址:https://gitcode.com/gh_mirrors/js/jstips
点击查看免费下载

相关推荐

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询