jQuery Callbacks lock() Method

Beginner
⏱️ 9 min read
📚 Updated: Jul 2026
🎯 5 Examples
🚀 5 Try-it labs
Freeze list

What You’ll Learn

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()

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().

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.

📝 Syntax

General form of callbacks.lock:

jQuery
callbacks.lock()

Parameters

  • None.

Return value

  • Returns the same Callbacks object (chainable).

Basic pattern

jQuery
const callbacks = $.Callbacks();



callbacks.add(function () { console.log("Registered"); });

callbacks.lock(); // freeze the list



callbacks.add(function () { console.log("Too late"); }); // ignored

callbacks.fire(); // → Registered

⚡ Quick Reference

GoalCode
Freeze handler listcallbacks.lock()
Check if lockedcallbacks.locked()
Fire after lockcallbacks.fire() — still works
Stop all firingcallbacks.disable()
Clear handlers (unlocked only)callbacks.empty()

📋 lock() vs disable()

Freeze the queue versus shut down firing entirely.

lock()
no add/remove

Blocks list mutations

disable()
no fire()

Blocks all invocation

fire()
lock yes

Works after lock, not after disable

Status
locked()

Pair with lock(); disabled() for disable()

Examples Gallery

Each example shows a different aspect of locking a Callbacks list.

📚 Getting Started

Lock after registration; late handlers are ignored.

Example 1 — Late add() After lock()

Only handlers registered before the lock run on fire().

jQuery
const callbacks = $.Callbacks();



callbacks.add(function () {

  console.log("First callback executed.");

});



callbacks.lock();



callbacks.add(function () {

  console.log("Second callback executed.");

}); // silently ignored



callbacks.fire(); // only first handler runs
Try It Yourself

How It Works

The second handler never joined the list — lock() blocked add(), not fire().

Example 2 — fire() Still Works After Lock

You can invoke handlers multiple times on a locked list.

jQuery
const callbacks = $.Callbacks();



callbacks.add(function (n) {

  console.log("Tick:", n);

});



callbacks.lock();

callbacks.fire(1);

callbacks.fire(2); // both fires succeed
Try It Yourself

How It Works

Locking protects the handler set from change — it does not pause or gate firing.

📈 Practical Patterns

Mutation guards, comparisons, and init workflows.

Example 3 — remove() Blocked After Lock

Handlers stay on the list even if you call remove() after locking.

jQuery
const callbacks = $.Callbacks();

const handler = function () { console.log("Still here"); };



callbacks.add(handler);

callbacks.lock();

callbacks.remove(handler); // ignored

callbacks.fire();          // → Still here
Try It Yourself

How It Works

empty() is also blocked after lock — the snapshot of handlers is preserved.

Example 4 — lock() vs disable()

Locked lists still fire; disabled lists do not.

jQuery
const locked = $.Callbacks();

locked.add(function () { console.log("locked: fired"); });

locked.lock();

locked.fire(); // → locked: fired



const disabled = $.Callbacks();

disabled.add(function () { console.log("disabled: fired"); });

disabled.disable();

disabled.fire(); // nothing
Try It Yourself

How It Works

Choose lock() when the subscriber set must stay fixed but events should still dispatch. Choose disable() for permanent shutdown.

Example 5 — End the Registration Phase

Lock hooks after plugin init so runtime code cannot add more subscribers.

jQuery
const Plugin = (function () {

  const hooks = $.Callbacks();



  return {

    onReady: hooks,

    init: function () {

      hooks.add(function () { console.log("Core ready"); });

      hooks.lock(); // registration closed

      console.log("Init complete — hooks locked");

    },

    run: function () { hooks.fire(); }

  };

})();



Plugin.init();

Plugin.onReady.add(function () { console.log("Too late"); });

Plugin.run();
Try It Yourself

How It Works

Exposing the Callbacks object publicly is fine — lock() ensures external add() calls after init cannot alter the handler set.

🚀 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.

📝 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.

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 Chrome All versions · Desktop & Mobile
Full support
Mozilla Firefox All versions · Desktop & Mobile
Full support
Apple Safari All versions · macOS & iOS
Full support
Microsoft Edge All versions · Chromium & Legacy
Full support
Internet Explorer IE 6+ · Legacy environments
Full support
Opera All modern versions
Full support
callbacks.lock() Universal

Bottom line: Safe in jQuery projects. Lock to freeze handlers; disable to stop firing.

🎉 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.

💡 Best Practices

✅ Do

  • Lock after the registration phase completes
  • Use locked() to verify lock state
  • Prefer disable() for plugin destroy/teardown
  • Document when external add() is allowed
  • 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

Key Takeaways

Knowledge Unlocked

Five things to remember about lock()

Freeze handler lists without stopping fire().

5
Core concepts
🚫 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.

Continue to locked()

Learn how to check whether a Callbacks list has been locked.

locked() tutorial →

About the author

Mari Selvan M P
Mari Selvan M P 🔗

Developer, cloud engineer, and technical writer

  • Experience 12 years building web and cloud systems
  • Focus Full Stack Development, AWS, and Developer Education

I write practical tutorials so students and working developers can learn by doing—from databases and APIs to deployment on AWS.

6 people found this page helpful