← jQuery eq()方法:按索引精准锁定单个元素 jQuery filter()方法:从元素集合中精准筛选目标 →

jQuery extend()方法:对象合并的实用技巧

原创 2026-05-01 jQuery 已有人查阅

在 JavaScript 开发中,对象合并是一个高频需求。jQuery 提供的 extend() 方法专门用于将两个或多个对象的内容合并到第一个目标对象中,并返回合并后的对象。它本质上是在帮你处理对象的浅拷贝和深拷贝问题,比手写循环合并要简洁且可靠得多。

extend() 是直接挂载在 jQuery 全局对象上的静态方法,调用形式为 $.extend(),而不是实例方法。这一点在使用时容易和插件开发中的 $.fn.extend() 混淆,后者是用来扩展 jQuery 原型链的,两者用途不同。

为什么我倾向于用 $.extend() 而不是 Object.assign()?

在现在 JavaScript 中,Object.assign() 已经可以完成基本的对象合并,但 extend() 有一个 Object.assign() 不具备的关键能力:递归合并。当你的对象包含嵌套的子对象时,Object.assign() 会把内层对象整体替换掉,而不是逐一合并属性。extend() 在传入 true 作为第一个参数后,会深度遍历每个属性,最终得到真正合并后的嵌套结构。这在处理配置文件、组件选项等场景中非常实用。

语法

jQuery.extend([deep], target, object1 [, objectN])

参数说明:

  • deep(可选):布尔值。设为 true 时启用深度递归合并,子对象不会直接被覆盖,而是逐层合并属性。

  • target:目标对象,所有后续对象的属性都会被合并到这里。这个方直接修改 target

  • object1:第一个合并源对象,其属性将被添加到 target 中。

  • objectN(可选):更多需要合并到 target 的源对象。

参数数量的特殊行为:

  • 只传一个参数:该参数被视为合并源,jQuery 对象自身成为目标,常用于为 jQuery 命名空间扩展功能。

  • 只传两个参数且无 deep:第一个参数是目标对象,第二个是源对象。

  • 传入 null 或 undefined 的源对象参数会被自动忽略,不会引发错误。

课程知识要点

  • 浅合并是默认行为:不传 deep 或 deep 为 false 时,遇到同名属性会直接用新值覆盖旧值,即使值是一个对象也会整体替换。

  • 深度合并需显式设置 deep: true:启用后,嵌套对象会递归合并,而不是被直接覆盖,适合处理多层结构的配置对象。

  • 直接修改目标对象extend() 会原地修改第一个对象参数,并返回它。如果你不想改动原始对象,可以把 {} 作为第一个参数传入。

  • 忽略 null 和 undefined:源对象中的 null 或 undefined 值也会覆盖目标属性。但如果合并源本身是 null 或 undefined,则会被整个跳过。

  • 数组不会被递归合并:即使开启深度合并,数组也是直接覆盖,不会把两个数组的元素进行合并。

示例一:默认浅合并

这个例子展示了两个对象在默认模式(非递归)下的合并效果。注意同名属性 Hindi 被整体替换,源对象中缺失的 Pages 属性不会从目标对象保留。

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>extend() 浅合并示例 · 编程学习</title>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
</head>
<body>
    <h4>extend() 方法——默认浅合并</h4>
    <p><b>对象 obj1 初始值:</b></p>
    <p id="origin1"></p>
    <p><b>对象 obj2:</b></p>
    <p id="origin2"></p>
    <p><b>obj2 合并到 obj1 后的结果:</b></p>
    <p id="result"></p>

    <script>
        var obj1 = {
            frontend: { price: 150 },
            backend: { price: 280 },
            database: { price: 300, pages: 275 }
        };
        var obj2 = {
            devops: { price: 200 },
            database: { price: 250, pages: 200 }
        };

        $("#origin1").text(JSON.stringify(obj1));
        $("#origin2").text(JSON.stringify(obj2));

        // 默认浅合并,obj1 被直接修改
        $.extend(obj1, obj2);

        $("#result").text(JSON.stringify(obj1));
    </script>
</body>
</html>

合并后你会发现,database 属性的值变成了 obj2 中的版本。原本 obj1.database 里 price: 300 和 pages: 275 都被源对象的对应值覆盖了。这就是浅合并的典型特征——对象类型的属性直接替换。

示例二:深度递归合并

启用深度合并后,嵌套对象的属性会逐层融合,而不是整体替换。下面的代码与示例一结构相似,但合并行为截然不同。

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>extend() 深度合并示例 · 编程学习</title>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
</head>
<body>
    <h4>extend() 方法——深度合并(deep: true)</h4>
    <p><b>对象 obj1 初始值:</b></p>
    <p id="origin1"></p>
    <p><b>对象 obj2:</b></p>
    <p id="origin2"></p>
    <p><b>深度合并后的结果:</b></p>
    <p id="result"></p>

    <script>
        var obj1 = {
            frontend: { price: 150 },
            backend: { price: 280 },
            database: { price: 300, pages: 275 }
        };
        var obj2 = {
            devops: { price: 200 },
            database: { pages: 180 },
            backend: { pages: 350 }
        };

        $("#origin1").text(JSON.stringify(obj1));
        $("#origin2").text(JSON.stringify(obj2));

        // 深度合并,第一个参数为 true
        $.extend(true, obj1, obj2);

        $("#result").text(JSON.stringify(obj1));
    </script>
</body>
</html>

这次的结果里,database 不再是整体替换,而是保留 obj1.database.price 不变,同时将 obj2.database.pages 合并进去。backend 也类似,price: 280 保留,pages: 350 作为新属性加入。这种深度合并的方式在合并用户配置与默认配置时特别有用。

个人经验与实用建议

在项目中,我几乎总是在合并配置对象时开启深度合并。一个典型场景是:组件内部有一套默认配置,用户在调用时传入自定义配置。如果不深度合并,用户传入的嵌套对象会直接替换整个默认子对象,导致其他默认值丢失,进而引发难以排查的运行时错误。

另外有一个容易忽略的细节:extend() 会直接修改第一个对象参数。如果你的目标是生成一个新对象而不改动原始对象,记得把空对象 {} 作为第一个参数传进去,像这样:

var merged = $.extend(true, {}, obj1, obj2);

这样 obj1 和 obj2 都不会被改动,结果保存在 merged 里。这个习惯在函数式编程风格或需要保留原始数据的场景下很重要,值得从一开始就养成。

← jQuery eq()方法:按索引精准锁定单个元素 jQuery filter()方法:从元素集合中精准筛选目标 →
分享笔记 (共有 篇笔记)
验证码:
微信公众号