在JavaScript中合并两个数组,现在大家用得最多的是原生方法 concat(),或者在ES6里直接用展开运算符 [...arr1, ...arr2]。那jQuery提供的 $.merge() 还有必要了解吗?说实话,在新项目里它确实用得少,但在维护老项目或者处理某些特定场景时,理解它的行为模式能帮你避开一些隐蔽的bug。
$.merge() 和 concat() 有一个根本性的差异:它不是在合并后返回一个新数组,而是直接把第二个数组的内容塞进第一个数组里,然后返回这个被修改后的第一个数组。
原地修改:需要格外警惕的特性
$.merge() 会直接改动传入的第一个数组。如果你在后面的代码里还要用到这个数组的原始内容,就会出问题。原始数据就这样悄无声息地被覆盖掉了。
这个设计也带来一个正面用途:如果你确实不需要保留第一个数组的原样,直接原地合并可以省去创建新数组的内存开销。在早期浏览器性能紧张的时候,这种微小的优化确实有存在的价值。
语法
jQuery.merge(first, second)
-
first:第一个数组。合并后,第二个数组的所有元素会被追加到这个数组的末尾,该数组会被直接修改。
-
second:第二个数组。它的内容会被合并进第一个数组,但自身不会被修改。
返回值是修改后的第一个数组的引用。
为什么更推荐原生的 concat()?
我个人在开发中,绝大多数情况都会优先使用原生的 Array.prototype.concat()。原因很明确:
-
concat()是不可变操作,返回一个新数组,原数组纹丝不动。这在数据流管理、状态变更追踪等场景里非常重要。 -
concat()的语义更清晰,一眼就能看出是在生成新数据,而不是在原数据上做手脚。
$.merge() 更像一个工具函数时代的产物。今天还在用它,多半是因为项目里已经到处是它的调用,保持风格统一。如果是新写的功能模块,直接用 concat() 或者展开运算符会更安全。
实战示例一:基本合并,观察原数组变化
这个例子用两个简单的分类数组来演示 merge() 的基本用法和它对第一个数组的修改效果。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>jQuery merge() 基本合并</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
</head>
<body>
<h4>jQuery merge() 方法示例</h4>
<p id="p1"><b>合并前 arr1(水果类): </b></p>
<p id="p2"><b>合并前 arr2(蔬菜类): </b></p>
<h4>点击按钮执行合并,并观察arr1的变化。</h4>
<button>执行合并</button>
<p id="p3"><b>合并后 arr1 的内容: </b></p>
<script>
$(document).ready(function() {
$("button").click(function() {
var arr1 = ["苹果", "香蕉", "橙子"];
var arr2 = ["白菜", "萝卜", "番茄"];
$("#p1").append(JSON.stringify(arr1));
$("#p2").append(JSON.stringify(arr2));
// 合并:arr1被直接修改,arr2保持不变
$.merge(arr1, arr2);
$("#p3").append(JSON.stringify(arr1));
});
});
</script>
</body>
</html>
点击按钮后可以看到,arr1 从原来的三个水果项变成了六个元素——水果在前,蔬菜在后。arr2 本身不受影响。这就是 merge() 的核心行为:目标数组被原地扩充。
实战示例二:合并多个数组时的嵌套调用
当需要合并三个或四个数组时,$.merge() 一次只能处理两个,所以需要通过嵌套调用来实现。这种写法读起来有点绕,但老项目里时不时能看到。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>jQuery merge() 多数组嵌套合并</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
</head>
<body>
<h4>合并四个数组到一个数组中</h4>
<p id="p1"><b>arr1: </b></p>
<p id="p2"><b>arr2: </b></p>
<p id="p3"><b>arr3: </b></p>
<p id="p4"><b>arr4: </b></p>
<h4>点击按钮,将四个数组合并进arr2。</h4>
<button>执行多重合并</button>
<p id="merge"><b>合并后的数组(arr2被修改): </b></p>
<script>
$(document).ready(function() {
$("button").click(function() {
var arr1 = ["前端", "后端", "全栈"];
var arr2 = ["JavaScript", "Python", "Java"];
var arr3 = ["Vue", "React", "Angular"];
var arr4 = ["MySQL", "MongoDB", "Redis"];
$("#p1").append(JSON.stringify(arr1));
$("#p2").append(JSON.stringify(arr2));
$("#p3").append(JSON.stringify(arr3));
$("#p4").append(JSON.stringify(arr4));
// 嵌套merge:从内到外执行,最终全部合并进arr2
$.merge(arr2, $.merge(arr1, $.merge(arr3, arr4)));
$("#merge").append(JSON.stringify(arr2));
});
});
</script>
</body>
</html>
嵌套的执行顺序是从最内层开始的:arr3 和 arr4 先合并进 arr3(arr3被修改),然后 arr1 和修改后的 arr3 合并进 arr1,之后 arr2 和 arr1 合并进 arr2。最终 arr2 包含了四个数组的全部元素。虽然能实现目标,但这种嵌套写法可读性实在一般,在代码审查中,我通常会建议换成更直观的统一收集后再处理的做法。
实战示例三:保护原始数据——先复制再合并
如果既想利用 $.merge() 的便利,又不想破坏原始数组,技巧是先把空数组作为第一个参数,让它来承接合并结果。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>jQuery merge() 保护原始数组</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
</head>
<body>
<h4>用空数组保护原始数据不被修改</h4>
<p id="p1"><b>arr1: </b></p>
<p id="p2"><b>arr2: </b></p>
<h4>点击按钮合并,但保留arr1和arr2的原值。</h4>
<button>安全合并</button>
<p id="merge"><b>合并结果(新数组): </b></p>
<p id="p4"></p>
<script>
$(document).ready(function() {
$("button").click(function() {
var arr1 = ["HTML", "CSS", "JavaScript"];
var arr2 = ["Node.js", "Express", "MongoDB"];
$("#p1").append(JSON.stringify(arr1));
$("#p2").append(JSON.stringify(arr2));
// 用一个空数组[]作为第一个参数来承接合并结果
// arr1和arr2都不会被改动
var merged = $.merge($.merge([], arr1), arr2);
$("#merge").append(JSON.stringify(merged));
$("#p4").html(
"<b>arr1 合并后仍然不变: </b>" + JSON.stringify(arr1) +
"<br><b>arr2 合并后仍然不变: </b>" + JSON.stringify(arr2)
);
});
});
</script>
</body>
</html>
这里把空数组 [] 作为最外层的承接容器,arr1 先合并进去,再把 arr2 也合并进去。最终合并结果存在新数组里,arr1 和 arr2 都保持了原始内容。这种方式在逻辑上等价于原生 concat() 的 arr1.concat(arr2)。
本节课程知识要点
-
$.merge()将第二个数组的内容原地追加到第一个数组中,直接修改第一个数组并返回它的引用,第二个数组不会被修改。 -
语法
jQuery.merge(first, second)中,两个参数都是必填的,返回值就是被修改后的first数组。 -
如果需要合并三个或更多数组,必须通过嵌套调用来实现,例如
$.merge(arrA, $.merge(arrB, arrC)),但可读性会随着嵌套层数增加而下降。 -
如果希望在合并的同时保留原始数组不被破坏,可以用空数组作为第一个参数来承接结果,即
$.merge($.merge([], arr1), arr2)。 -
在现在JavaScript开发中,
Array.prototype.concat()或ES6的展开运算符[...arr1, ...arr2]因为其不可变性和更清晰的语义,通常是更优先的选择;$.merge()更多出现在历史遗留项目中。