jQuery.sub() created a writable copy of jQuery so you could add or override methods without changing the global $. This tutorial covers the official use cases, why it was not a sandbox, why it was removed in 1.9, and what to use instead — with five legacy labs on jQuery 1.8.3.
01
$.sub()
Copy jQuery
02
Private
fn methods
03
Override
Safely
04
Plugins
Return sub$
05
Removed
Since 1.9
06
1.5+
Added
Fundamentals
Introduction
Plugin authors sometimes need helper methods that must not appear on the global jQuery.fn, or they want to override .remove() / .html() only inside a controlled copy of jQuery. Before ES modules were common, jQuery.sub() offered that fork.
Added in jQuery 1.5, jQuery.sub() returns a new jQuery constructor. Methods you add to sub$.fn stay on that copy. The original jQuery / $ remains unchanged for the rest of the page.
The API was deprecated in 1.7 and removed in 1.9. Modern projects should not call $.sub(). This page teaches it so you can read legacy plugins and migrate to modules or the widget factory. See the Utilities hub for current helpers.
Concept
Understanding the jQuery.sub() Method
jQuery.sub() takes no arguments. It returns a function that behaves like jQuery for selecting and chaining, but you can freely assign new properties on that function and on its .fn prototype.
Important limitation from the official docs: sub() is not isolation. Events, Ajax, and element data still use the main jQuery. Only the jQuery object you extend is a separate copy.
⚠️
Removed in jQuery 1.9
typeof jQuery.sub is "undefined" in jQuery 3.x. Try-it labs load jQuery 1.8.3 (last 1.8 release that still includes $.sub()). Prefer the jQuery UI widget factory for new stateful plugins.
Foundation
📝 Syntax
Create a private jQuery copy (jQuery 1.5–1.8 only):
jQuery
jQuery.sub()
// or
$.sub()
Parameters
None — the method accepts no arguments.
Return value
A new jQuery constructor function (same shape as jQuery / $).
Extend it with sub$.fn.myMethod = … or sub$.fn.extend({ … }).
Official starter pattern
jQuery
(function() {
var sub$ = jQuery.sub();
sub$.fn.myCustomMethod = function() {
return "just for me";
};
sub$( document ).ready(function() {
sub$( "body" ).myCustomMethod(); // "just for me"
});
})();
// jQuery( "body" ).myCustomMethod → undefined on the global $
Cheat Sheet
⚡ Quick Reference
Goal
Code (jQuery 1.5–1.8)
Fork jQuery
var sub$ = jQuery.sub();
Add private method
sub$.fn.help = function(){ … };
Override then call original
return jQuery.fn.remove.apply(this, arguments);
Plugin returns sub copy
return plugin( this );
Modern jQuery 3.x
typeof $.sub === "undefined"
Compare
📋 $.sub() vs $.noConflict() vs widget factory
Three different tools — only one creates an editable jQuery fork.
jQuery.sub()
fork API
Copy of jQuery you can extend privately — removed in 1.9
$.noConflict()
free $
Releases the global $ name — does not create a method fork
Widget factory
plugins
Recommended for stateful plugins with private methods
ES module / IIFE
today
Keep helpers private without forking jQuery itself
Hands-On
Examples Gallery
Examples follow the official jQuery API documentation. Labs use jQuery 1.8.3 because $.sub() does not exist in 1.9+.
📚 Getting Started
Official patterns for private methods and safe overrides.
Example 1 — Official: Private Method on a Sub
Add myCustomMethod only on the subbed jQuery — not on the global $.
jQuery
(function() {
var sub$ = jQuery.sub();
sub$.fn.myCustomMethod = function() {
return "just for me";
};
sub$( document ).ready(function() {
sub$( "body" ).myCustomMethod(); // "just for me"
});
})();
typeof jQuery( "body" ).myCustomMethod; // undefined
sub$("body").myCustomMethod() → "just for me"
typeof jQuery("body").myCustomMethod → "undefined"
Private helper stays off the global jQuery.fn
How It Works
An IIFE creates sub$, attaches a method to sub$.fn, and uses only that copy inside the closure. Outside code that calls the normal $ never sees myCustomMethod.
Example 2 — Official: Override .remove() Privately
Trigger a custom remove event before calling the real jQuery remove — only on the sub copy.
jQuery
(function() {
var myjQuery = jQuery.sub();
myjQuery.fn.remove = function() {
this.trigger( "remove" );
return jQuery.fn.remove.apply( this, arguments );
};
myjQuery(function( $ ) {
$( ".menu" ).on( "click", function() {
$( this ).find( ".submenu" ).remove();
});
$( document ).on( "remove", function( event ) {
$( event.target ).parent().hide();
});
});
})();
// Global jQuery.remove does not fire this custom event
Clicking .menu removes .submenu via myjQuery
Custom "remove" event fires only through the sub copy
Global $.fn.remove remains the stock implementation
How It Works
Override myjQuery.fn.remove, call the original with jQuery.fn.remove.apply(this, arguments), and keep all app code inside myjQuery(function($){ … }) so the local $ is the subbed copy.
📈 Practical Patterns
Plugin chaining and migration awareness.
Example 3 — Official: Plugin That Returns Plugin Methods
Expose open / close only after calling .myplugin(), which returns a subbed collection.
jQuery
(function() {
var plugin = jQuery.sub();
plugin.fn.extend({
open: function() { return this.show(); },
close: function() { return this.hide(); }
});
jQuery.fn.myplugin = function() {
this.addClass( "plugin" );
return plugin( this );
};
})();
$( "#main" ).myplugin().open();
// $( "#main" ).open() would fail — open lives only on the plugin copy
#main gets class "plugin"
.myplugin().open() shows the element
typeof $("#main").open === "undefined" on plain $
How It Works
The public entry point is still on global jQuery.fn, but it returns plugin(this) so chained methods like .open() resolve on the subbed prototype. Callers must go through .myplugin() first.
Example 4 — Prove the Global $ Is Untouched
Add a method on sub$ and confirm $.fn does not gain it.
typeof jQuery.sub → "undefined" (jQuery 3.7.1)
Use closures / modules / widget factory instead
Do not ship new code that depends on $.sub()
How It Works
Removal means migration is mandatory. Keep private functions in module scope and expose a single $.fn entry point, or adopt the widget factory for richer plugins.
Applications
🚀 Historical Use Cases
Private plugin helpers — methods only available on the subbed jQuery.
Safe method overrides — customize .remove() / .html() without patching the global.
Chained plugin APIs — return a subbed collection that exposes open / close.
Reading legacy code — recognize jQuery.sub() in old plugins during upgrades.
Not for isolation — never treat sub() as a security sandbox or separate event bus.
🧠 How jQuery.sub() Worked
1
Call jQuery.sub()
Receive a new constructor that mirrors the public jQuery API.
Fork
2
Extend the copy
Add or override methods on sub$.fn inside your closure.
Extend
3
Use the subbed $
Select and chain with sub$ so private methods resolve correctly.
Call
4
✓
Global jQuery stays intact
Other scripts keep the original API; events/Ajax still share the main jQuery.
Important
📝 Notes
Added in jQuery 1.5; deprecated in 1.7; removed in 1.9.
Accepts no arguments; returns a jQuery-like constructor.
Not a sandbox — events, data, and Ajax still use the main jQuery.
For plugin state and sub-methods today, prefer the jQuery UI widget factory.
Do not confuse with $.noConflict() (global name management only).
Try-it labs 1–4 use jQuery 1.8.3; lab 5 uses jQuery 3.7.1 to show removal.
Compatibility
Availability
jQuery.sub() existed only in jQuery 1.5–1.8. It is not present in jQuery 1.9+, 2.x, 3.x, or 4.x. There is no polyfill in core jQuery Migrate for restoring $.sub(). Treat this page as historical documentation for upgrades.
✓ Removed · jQuery 1.9+
jQuery.sub() — legacy only
Works in jQuery 1.5–1.8 builds. Modern evergreen browsers running jQuery 3.x will report typeof $.sub === "undefined". Migrate plugins or rewrite encapsulation.
0%In jQuery 3.x
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
$.sub()Removed
Bottom line: Use modules or the widget factory — do not depend on $.sub() in new code.
Wrap Up
Conclusion
jQuery.sub() forked the jQuery API so plugins could keep private methods or overrides without polluting the global $. It never isolated events or Ajax, and jQuery removed it in 1.9.
When you meet $.sub() in old code, rewrite with closures, modules, or the widget factory. Next up: jQuery.noConflict().
Treat $.sub() as legacy documentation when upgrading apps
Keep plugin helpers in module/IIFE scope on modern jQuery
Use the widget factory for stateful UI plugins
When overriding on a sub copy, always call the original via jQuery.fn.*
Pin try/demos to jQuery 1.8.x only when you must reproduce sub()
❌ Don’t
Ship new features that require jQuery.sub()
Expect isolation of Ajax, events, or .data()
Assume Migrate will restore $.sub() on jQuery 3
Confuse sub() with noConflict()
Patch global $.fn when a private copy was the original intent
Summary
Key Takeaways
Knowledge Unlocked
Five things to remember about jQuery.sub()
A removed fork API for private jQuery extensions.
5
Core concepts
⧉01
Fork
jQuery
Copy
🔒02
Private
Methods
fn
≠03
Not
Sandbox
Shared
✕04
Gone
Since 1.9
Removed
→05
Use
Modules
Today
❓ Frequently Asked Questions
jQuery.sub() returned a new copy of the jQuery function whose properties and methods you could change without modifying the global jQuery / $ object. Private plugin methods and method overrides lived on that copy. Added in jQuery 1.5.
No. It was deprecated in jQuery 1.7 and removed in jQuery 1.9. Modern jQuery 3.x does not include $.sub(). Try-it labs on this page load jQuery 1.8.3 so you can still run authentic historical demos.
No. Official docs stress that sub() is not sandbox isolation. Events, .data(), and Ajax still go through the main jQuery. Only the jQuery function object and its fn methods are copied so you can extend or override them privately.
Two cases: (1) override methods like .remove() on a private copy without changing global jQuery, and (2) basic plugin encapsulation so helper methods exist only on the subbed instance. For new plugins, prefer the jQuery UI widget factory or plain modules.
noConflict() restores the previous global $ and can release the jQuery name — it does not create a fork of the API. sub() kept the same global jQuery and gave you a second, editable copy for private extensions.
Use ES modules or IIFEs for private helpers, jQuery.fn plugins that return the original collection, or the jQuery UI widget factory for stateful plugins. Do not rely on $.sub() in new code — it is gone from modern jQuery.
Did you know?
jQuery.sub() lived a short life: born in 1.5, deprecated two minors later in 1.7, and deleted in the 1.9 cleanup that also removed jQuery.browser and other legacy APIs. The jQuery team pointed plugin authors toward the UI widget factory instead of maintaining a second jQuery constructor in core.