The lock() method freezes a Callbacks list in its current state — no more add(), remove(), or empty() — while fire() still runs registered handlers. This tutorial covers syntax, five examples, and how lock() differs from disable().
01
Syntax
callbacks.lock()
02
Freeze
No add/remove
03
fire()
Still works
04
vs disable()
Different goal
05
locked()
Status check
06
Permanent
No unlock()
Fundamentals
Introduction
During plugin setup or event wiring, you often register handlers with add(). But once initialization is complete, you may want to prevent late code from adding or removing subscribers — while still allowing fire() to notify everyone already on the list.
lock() does exactly that. It snapshots the handler queue and blocks further mutations. The old reference incorrectly described lock() as blocking callback invocation or providing a “release” mechanism — jQuery’s lock() is about freezing the list, not pausing fire().
Concept
Understanding the lock() Method
callbacks.lock() locks the Callbacks list in its current state. After locking, mutating methods — add(), remove(), and empty() — silently do nothing. Handlers registered before the lock remain and still run when you call fire() or fireWith().
There is no unlock() method. Once locked, the list stays locked for the lifetime of that object. Use locked() to check whether locking has occurred.
💡
Beginner Tip
Memory trick: lock() locks the list; disable() kills firing. lock = protect subscribers; disable = shut down entirely.
Exposing the Callbacks object publicly is fine — lock() ensures external add() calls after init cannot alter the handler set.
Applications
🚀 Use Cases
Plugin init — close registration after setup completes.
Deferred-style flows — lock callback queues before resolving (jQuery uses this internally).
Immutable subscriber sets — guarantee the handler list cannot change at runtime.
Defensive APIs — prevent third-party code from removing core handlers.
Testing — assert locked() is true after a lifecycle milestone.
🧠 How lock() Freezes the List
1
add() handlers
Register subscribers during setup or init.
Register
2
lock()
List snapshot taken; add/remove/empty blocked.
Freeze
3
fire()
Registered handlers still run normally.
Invoke
=
✅
Stable handler set
Subscribers cannot change, but events still dispatch.
Important
📝 Notes
lock() blocks mutations, not fire() or fireWith().
There is no unlock() — locking is permanent for that list object.
Check status with locked(), not disabled().
disable() is stronger — it prevents firing and clears internal state.
Call lock() only after all intended handlers are registered.
Compatibility
Browser Support
callbacks.lock() is part of jQuery’s Callbacks API since jQuery 1.7 and works wherever jQuery runs.
✓ jQuery 1.7+
jQuery Callbacks.lock()
Supported in jQuery 1.x, 2.x, and 3.x. Lock behavior is consistent across browsers.
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
callbacks.lock()Universal
Bottom line: Safe in jQuery projects. Lock to freeze handlers; disable to stop firing.
Wrap Up
🎉 Conclusion
The callbacks.lock() method freezes a Callbacks list so add(), remove(), and empty() no longer change it — while fire() continues to notify registered handlers. It is the right tool when you need a stable subscriber set, not when you want to stop firing entirely.
Next, learn locked() to check whether a list has been locked.
Fire freely on locked lists when events should still flow
❌ Don’t
Expect lock() to block fire()
Look for an unlock() method — it does not exist
Confuse lock() with disable()
Lock before all required handlers are added
Assume late add() throws — it fails silently
Summary
Key Takeaways
Knowledge Unlocked
Five things to remember about lock()
Freeze handler lists without stopping fire().
5
Core concepts
🔒01
lock()
Freeze list
API
🚫02
add/remove
Blocked
Mutate
▶03
fire()
Still runs
Invoke
🛑04
disable()
Stops firing
Compare
?05
locked()
Status check
Pair
❓ Frequently Asked Questions
lock() freezes the Callbacks list in its current state. After locking, add(), remove(), and empty() become no-ops — they silently do nothing. Handlers already registered stay on the list.
No. fire() and fireWith() still invoke every handler that was registered before lock(). lock() blocks list mutations, not invocation.
lock() freezes the queue — no more add/remove, but fire() still works. disable() permanently shuts down firing — fire() becomes a no-op. Use lock() to protect the handler set; use disable() for teardown.
No. jQuery provides no unlock() method. lock() is permanent for that Callbacks object. Check status with locked(), which returns true after lock().
Common uses: end a registration phase so late subscribers cannot add handlers, snapshot hooks before firing in Deferred-style flows, and protect plugin callback lists after initialization.
No. The syntax is simply callbacks.lock() with no arguments. Flags belong on $.Callbacks() at creation time, not on lock().
Did you know?
jQuery’s Deferred implementation locks its internal Callbacks lists when a deferred resolves or rejects. That prevents new done/fail handlers from being added in certain edge cases — the same lock() mechanism you use in plugin code.