What can we learn from jQuery? Patterns it uses.

Artem Deikun
FED is love — Front-End
5 min readAug 15, 2019

--

Nowadays jQuery is still one of the most popular libraries but not many developers know how it’s built. Let’s take a look at some patterns in JavaScript development that has been used in the source code of jQuery library.

In every section, I will provide a regular implementation of the pattern in JS and simplify version of jQuery approach.

As a summary of this publication, you will get a small jQuery library with full understanding.

IIFE. Exposing public variables

It’s a regular practice to use Immediately Invoked Function Expression for hiding variables and avoid conflicts with the global scope.

Regular implementation

Declare function and invoke it in one line.
Parameters of this functions is a reference to the global object (window).
In the body of IIFE put all logic.

https://gist.github.com/artemhp/4d7cb4cad231c6dcccfe262b017c623c

How jQuery does it

All logic of the library is located in the function factory that actually not the body of IIFE but its parameter.

In the body of IIFE, the factory function invokes with different parameters depending on the environment.

For NodeJS environment without DOM IIFE returns a function. That function can be run with any window object.

https://gist.github.com/artemhp/badabd55c9df2499a25819520aa8a7c1

By this approach, jQuery is usable in Browser, Node.JS, and module ecosystem environments

  • In the case of CommonJS:
    The condition with module.exports is true and the factory will be invoked with parameter noGlobal = true. Because in CommonJS has no document property but the library will be still available in the context of the module.
  • In case of <script src=”jquery.js” />
    Like in regular scenario factory function will be executed and expose jQuery to the global scope and it will be possible to use it as $ or jQuery.
  • In the case of using jQuery in the Node.JS script for SSR.
    On require(‘jquery’) in NodeJS script, you will get not object jQuery($) but function in which you have to pass window with DOM. About this approach, I will describe in the next section — Currying.

It teaches us how to

  • We should care about all environments that are possible to use.
  • Encapsulate logic and scope inside the context of the function.

Create an instance of jQuery object

In JS there are lot’s of methods how to create an object.
For creating an instance of an object jQuery use approach — using the function constructor + prototype.

Regular implementation

Define a function that we assume will be a constructor.
Create an object using “new” keyword (constructor call).
Add new properties by prototype or inside “function constructor”.

https://gist.github.com/artemhp/bb2ed8c21fc5eae369b8b8fb49b93c66

How jQuery does it

Function jQuery exposes in the global scope and by execution, it returns the constructed jQuery object.

jQuery.fn — is an alias for jQuery.prototype.

The function that in the conclusion will eventually beсome a constructor and provide all functionality to jQuery object is jQuery.fn.init.

Function constructor call is not explicit. The object that is created with “new” keyword is returning inside jQuery function statement.

Here is the minimalistic jQuery pattern of creating an object:

https://gist.github.com/artemhp/9de1fc853460fe3bcb3b632c0299a39b

I hope, that by clean up I didn’t remove necessary rows that help to illustrate the main concept of this approach.

It teaches us how to

  • jQuery library separates the complexities of the creation logic from the final representation as much as it is possible. Developer by using jQuery creates an instance of jQuery object even without “new” keyword.
  • As a result, we have a nice object structure inside the module:
    jQuery as the main public function (it’s easy to maintain and resolve conflicts)
    jQuery.fn as an alias to the prototype.
    jQuery.fn.init — function constructor.
  • By creating a new prototype it’s easy to add methods that have been overwritten with: [].push, [].splice, Object.getPrototypeOf, etc.

Method chain

“Chain of Responsibility” pattern is pretty popular in JavaScript — repeatedly calling one method after another on an object, in one continuous line of code.
jQuery library is always mentioned in the explanation of this pattern.

Regular implementation

This solution can be possible because of “this” keyword.

https://gist.github.com/artemhp/d36d75b4d493156d9cc2814a8bca01ec

How jQuery does it

In most of the methods in jQuery it has a regular implementation.
But is some cases (operating with nodes) use a stack and user is able to get the previous node.

By adding method pushStack in prototype jQuery provide an ability for a user to get the previous node. This very creates some sort of stack in the chain of nodes.

In any method that operates with nodes (find for example) not ‘this’ but this.pushStack should be returned. In that place — the previous stack of nodes is saved.

Method end in the chain returns the previously selected node.

https://gist.github.com/artemhp/3122debde0e923c0b7fc2b37be650796

It teaches us how to

  • Create a user-friendly solution.
  • Provide to developer ability to solve lots of task in a single chain operating with different parts of DOM.
  • Pay attention to approaches on how to use the stack in JS.

Summary

By using three patterns during writing this publication was created an analog of the cross-platform jQuery library in 42 rows of code.

This code snippet of hybrid of jQuery will just select Node.
You can extend a prototype by adding any method to modify elements.

In the example above I have added method style and it’s possible to change styles for selected elements.

Hope this publication was useful for you, and you will try to invest your time not just to learn how to use libraries or frameworks, but interested in how they build.

--

--