Calling jQuery .end() Without Traversal Operations

Calling the jQuery .end() method without a preceding traversal or filtering method causes jQuery to return an empty jQuery object. This article explores how jQuery manages its internal selection stack using the prevObject property, what happens under the hood when .end() is invoked prematurely, and how this behavior affects the rest of your chained script.

How jQuery Manages Traversal History

jQuery tracks changes to the selected elements using an internal stack. Whenever you invoke a "destructive" traversal method—such as .find(), .filter(), .children(), or .parent()—jQuery constructs a new jQuery object containing the matched elements and attaches a reference to the previous collection in an internal property named prevObject.

The .end() method is designed to pop the current selection off this stack and return the previous jQuery object stored in prevObject.

The Result of Calling .end() Without Traversal

When you initialize a jQuery object directly using a selector (for example, $('div')), jQuery creates the primary collection. At this initial stage, there is no previous traversal state. To maintain consistent object structure, jQuery sets the initial prevObject to an empty jQuery object (or one referencing the document context with an element count of zero).

If you call .end() immediately on this base selection:

const $elements = $('div').end();
console.log($elements.length); // Outputs: 0

Because there is no preceding DOM traversal operation to revert to, .end() resolves to that base prevObject, returning a jQuery wrapper that contains zero elements.

Impact on Chained Operations

JavaScript will not throw an error if you call .end() without a prior traversal step. Instead, the method fails silently by passing an empty set down the chain. Any subsequent methods applied to the chain will execute against zero nodes:

// The .hide() method does nothing because .end() emptied the selection
$('div').end().hide(); 

In this scenario, .hide() executes without errors, but no div elements on the page will actually be hidden because the active selection was cleared by .end().

Proper Usage

To avoid unintentionally emptying your element set, ensure every .end() call is paired with a prior filtering or traversal operation. Only use .end() when you need to step back out of a nested selection context and return to the parent or broader matched set previously targeted in the chain.