The jQuery.extend() utility merges properties from one or more objects into a target object. This tutorial covers shallow vs deep merge, the plugin defaults pattern, extending the jQuery namespace, five worked examples, comparisons with Object.assign(), and security notes for untrusted input.
01
Syntax
$.extend(t, s)
02
Shallow
Replace nested keys
03
Deep
true first arg
04
Defaults
{} target
05
Return
Same target ref
06
Plugins
Single-arg form
Fundamentals
Introduction
Real-world JavaScript often needs to combine configuration objects — default settings with user options, partial API responses with cached data, or feature flags spread across several sources. jQuery provides jQuery.extend() (also written $.extend()) as a battle-tested merge utility that has been part of the library since jQuery 1.0.
Unlike spread syntax or Object.assign(), which only perform shallow copies, $.extend(true, target, source) can recursively merge nested plain objects and arrays — a pattern plugin authors rely on every day.
Concept
Understanding the jQuery.extend() Method
jQuery.extend(target, object1 [, objectN]) copies enumerable properties from each source object into target. Later sources overwrite earlier ones for the same key. The method returns the modified target reference. Arguments that are null or undefined are skipped.
When the first argument is the boolean true, the merge becomes deep: nested plain objects and arrays are merged recursively instead of being replaced wholesale. Properties with value undefined are never copied.
💡
Beginner Tip
To keep your original defaults untouched, always merge into a fresh empty object: var settings = $.extend({}, defaults, options). This is the most common plugin-development pattern in jQuery.
Foundation
📝 Syntax
Three common forms of jQuery.extend:
jQuery
// Shallow merge into target
jQuery.extend( target, object1 [, objectN ] )
// Deep (recursive) merge
jQuery.extend( true, target, object1 [, objectN ] )
// Add properties to the jQuery namespace (single argument)
jQuery.extend( object )
Parameters
target — the object that receives merged properties. It is modified in place.
object1 … objectN — one or more source objects whose properties are copied into the target.
true (optional first flag) — enables deep recursive merge. Passing false explicitly is not supported.
Return value
Returns the target object (same reference, now containing merged properties).
The empty {} target absorbs all properties. options overrides validate and name; limit falls through from defaults. Both source objects remain untouched for the next plugin invocation.
Example 4 — Merge Three Sources into One
Later objects win on duplicate keys — useful when layering base config, environment overrides, and runtime flags.
jQuery
var base = { theme: "light", timeout: 5000, retries: 3 };
var env = { timeout: 8000 };
var runtime = { retries: 1, debug: true };
var config = $.extend({}, base, env, runtime);
console.log(JSON.stringify(config));
// {"theme":"light","timeout":8000,"retries":1,"debug":true}
jQuery processes sources left to right. env overrides timeout; runtime then overrides retries and adds debug. theme survives from base because no later source defines it.
Example 5 — Extend the jQuery Namespace
With a single argument, properties are added directly to jQuery / $ — how plugins register global helpers.
jQuery
$.extend({
greet: function (name) {
return "Hello, " + name + "!";
}
});
console.log($.greet("World")); // "Hello, World!"
When the target argument is omitted, jQuery assumes itself is the target. The new greet function becomes available as $.greet. For instance methods on DOM selections, use $.fn.extend() instead.
Applications
🚀 Common Use Cases
Plugin configuration — merge default options with caller-supplied settings.
Layered config — combine base, environment, and runtime objects into one settings blob.
Partial API merge — overlay a fresh response onto cached data without losing unrelated keys (use deep extend for nested fields).
Register utilities — add functions to $ or $.fn via the single-argument or $.fn.extend forms.
Clone with overrides — $.extend({}, original, patch) for immutable-style updates.
Detect deep flag (true), identify target, skip null/undefined sources.
Setup
2
Copy properties
Walk each source left to right; copy enumerable keys whose values are not undefined.
Merge
3
Resolve conflicts
Shallow: replace whole nested values. Deep: recurse into plain objects and arrays.
Depth
4
📦
Return target
The modified target reference is returned for chaining or reuse.
Important
📝 Notes
Available since jQuery 1.0; deep merge since jQuery 1.1.4.
Passing false as the deep flag is not supported — omit it or pass true.
Deep-extending cyclical (circular) structures throws an error.
Date, RegExp, and custom class instances are not reconstructed — they become plain objects in deep merge results.
jQuery versions before 3.4 had a __proto__ pollution risk with deep extend on untrusted input — sanitize user objects in security-sensitive apps.
For DOM plugin methods, use $.fn.extend() to add methods to jQuery selections, not the single-arg $.extend() form.
Compatibility
Browser Support
jQuery.extend() has been part of jQuery since jQuery 1.0+ (deep merge since 1.1.4). It works wherever jQuery runs — all modern browsers and legacy IE when paired with a supported jQuery build.
✓ jQuery 1.0+
jQuery jQuery.extend()
Supported in jQuery 1.x, 2.x, and 3.x. One of the most widely used utilities in the jQuery ecosystem.
100%With jQuery loaded
Google ChromeAll versions · Desktop & Mobile
Full support
Mozilla FirefoxAll versions · Desktop & Mobile
Full support
Apple SafariAll versions · macOS & iOS
Full support
Microsoft EdgeAll versions · Chromium & Legacy
Full support
Internet ExplorerIE 6+ · Legacy environments
Full support
OperaAll modern versions
Full support
jQuery.extend()Universal
Bottom line: Safe in any project that already includes jQuery. For greenfield apps without jQuery, consider native Object.assign() or structuredClone() for shallow/deep copy needs.
Wrap Up
Conclusion
The jQuery.extend() utility is the standard way to merge object properties in jQuery projects. Use shallow merge for flat configs, deep merge for nested settings, and the empty-object target pattern to protect your defaults.
Practice the five examples above until shallow vs deep behavior feels intuitive — then explore jQuery.merge() when you need to append arrays instead of object keys.
Use $.extend({}, defaults, options) to preserve sources
Pass true first when nested objects must merge recursively
Layer configs left-to-right with later sources overriding earlier ones
Use $.fn.extend() for selection methods on DOM plugins
Sanitize untrusted objects before deep extend (jQuery < 3.4)
❌ Don’t
Assume shallow merge preserves nested sub-objects
Pass false as the deep flag — it is unsupported
Deep-extend circular object graphs
Expect Date or RegExp instances to survive deep merge intact
Merge unsanitized user JSON with $.extend(true, {}, input) on old jQuery
Summary
Key Takeaways
Knowledge Unlocked
Five things to remember about jQuery.extend()
Merge object properties the jQuery way.
5
Core concepts
🔗01
$.extend
Merge into target
API
📄02
Shallow
Replace nested
Default
📑03
true flag
Deep merge
Recursive
🛠04
{} target
Safe defaults
Pattern
⚠05
undefined
Not copied
Skip
❓ Frequently Asked Questions
jQuery.extend() copies properties from one or more source objects into a target object. The target is modified in place and also returned. Use it to combine configuration objects, merge API responses, or add methods to the jQuery namespace.
By default, $.extend() performs a shallow merge: nested objects in the target are completely replaced by same-key properties from the source. Pass true as the first argument — $.extend(true, target, source) — for a deep (recursive) merge that combines nested plain objects and arrays.
Pass an empty object as the target: var settings = $.extend({}, defaults, options). The defaults object stays unchanged; settings receives a new merged copy.
No. Properties whose value is undefined are not copied. Inherited prototype properties on the source objects can be copied, however.
Object.assign() is shallow only and is native ES2015+. jQuery.extend() supports deep recursive merge with a true first argument and has long been the standard pattern in jQuery plugins for merging defaults and options.
When only one object is passed, jQuery itself is the target — the properties are added to the jQuery / $ namespace. Plugin authors use this to register $.myPlugin as a new global jQuery function.
Did you know?
The shallow-merge banana example on the official jQuery API page is famous for teaching one lesson: without true, $.extend(object1, object2) replaces entire nested objects rather than merging their inner keys. Always ask “do I need deep extend?” before merging config with nested settings.