Home Web Front-end JS Tutorial A brief discussion on jQuery core architecture design

A brief discussion on jQuery core architecture design

Jan 24, 2017 am 11:20 AM

jQuery is no stranger to everyone, so I won’t say much here about what it is and what it does. The purpose of this article is to discuss the core of jQuery through a simple analysis of the source code. Architectural design, and how jQuery leverages advanced features in JavaScript to build such a great JavaScript library.

1 First introduction to jQuery

From the core function point of view, jQuery only does one simple and ordinary thing: query. Its syntax is so concise and clear that many people have already used jQuery without knowing what javascript is. To describe it in one word, it is: simplicity and simplicity. From a design perspective, we can divide the methods provided by jQuery into two major categories: static methods and instance methods. Static methods are methods accessed directly through $. These methods generally do not operate on DOM elements, but provide some common tools, such as ajax requests and some common operations on strings. In addition, jQuery also provides With its own extension mechanism, you can write the components you need through the extend method. The instance method is different from the static method. It is used to operate on the DOM elements queried by jQuery. jQuery executes $() to construct a jQuery object. This object stores all the DOM elements queried in an array method, and then in this The object's prototype chain implements methods for operating these DOMs. For example, the each() method is used to traverse each DOM element. You may notice that I just said that this object is stored "as an array", that is to say, the object constructed by jQuery is not an array, so what exactly is this object? In fact, this object is the core of jQuery, also known as "jQuery object". Therefore, the focus of this article is to analyze and discuss jQuery objects.

2 jQuery object

Generally, we will use jQuery like this:

$('div').each(function(index){     //this ...});
Copy after login

$('div') After execution, a jQuery object is returned. The each() method traverses the DOM elements in this object. Let's first look at the execution process of $('div') (the source code of this article is taken from jQuery 3.0):

jQuery = function( selector, context ) {    
    return new jQuery.fn.init( selector, context );

}
Copy after login

This method is the entry method of $('div'). $ is the abbreviation of jQuery, which is equivalent to jQuery('div'). It can be seen that this method only does one thing. That is to return the instance object of the jQuery.fn.init() function. So what is jQuery.fn.init? Let’s look at the following code:

init = jQuery.fn.init = = jQuery.fn;
Copy after login

jQuery.fn. init and init refer to the same method. This method queries the qualified DOM elements based on the selector and returns them. But you will find that what is returned is this. What is this? We will analyze it later. Let’s first look at the following sentence:

init.prototype = jQuery.fn;
Copy after login

What does this sentence mean? This sentence makes the prototype object of the init method point to the jQuery.fn object. , so what the hell is jQuery.fn? Let's continue to look at the code:

jQuery.fn = jQuery.prototype = {    // The current version of jQuery being used    jquery: version,

    constructor: jQuery,    // The default length of a jQuery object is 0
    length: 0,    // Execute a callback for every element in the matched set.
    each: function( callback ) {        return jQuery.each( this, callback );
    },
       
    splice: arr.splice
};
Copy after login

In order to save space, I have omitted some of the code. As can be seen from here, jQuery.fn is actually the prototype object of jQuery. This prototype object is defined in There are some methods to operate on this object. If you feel a little confused at this point, don't worry, let's sort out the ideas: jQuery first defines an init method, and then defines a series of operation methods on the init prototype object prototype. Finally, the instance object of the init method is returned. So the above process can be simplified as follows (pseudocode representation):

var init = function(selector,context,root){   //...   return this;
}

init.prototype = {
   length:0,
   each:function(callback){      //...   },
   splice:[].splice
}

jQuery = function(selector,context,root){   return new init(selector,context,root);
}
Copy after login

Then the question is, why are the methods in jQuery.fn not directly defined on the init prototype, but defined On jQuery's prototype object?

Actually, the purpose of this is to improve the query efficiency of jQuery. If it is directly defined on the prototype object of init, then every time a query is executed, such a huge prototype object will be created in the memory, and If this object is defined on jQuery's prototype, this object will be initialized when jQuery is loaded and will always exist in memory. Every time $() is executed in the future, you only need to point the prototype in init to this object. Instead of creating the same object every time.

Let’s take a look at what exactly this is returned in the init function. I said in my previous blog that this in the function always points to the caller during runtime. So who is the caller of init? ? It seems that the caller cannot be found in the above code. At this time, we need to deeply understand the operating mechanism of the new operator. Borrowing from my previous description of the new operator in my blog, we will carry out the execution process of new init(). It’s broken down as follows:

new init(selector,context,root) = {    var obj = {};

    obj.__proto__ = init.prototype;

    init.call(obj,selector,context,root);    return typeof result === 'obj'? result : obj;

}
Copy after login

It can be seen from the above decomposition process that when JavaScript creates an instance object through new, it will first create a common object obj, and then point the internal attribute __proto__ of obj to the prototype object of init, so obj The prototype chain will be changed, and step 3 uses the call method to call init(), so this in init refers to the obj object here.

After init() is executed, will store all matched DOM objects in the form of an array into this object and return it, that is, the obj object will be returned, and the new operator will eventually This obj object is returned as the new instance object. So the instance object returned by the new operator has two characteristics: first, it contains the DOM query result set, and second, its prototype chain inherits the prototype of init, and the prototype of init points to the jQuery.fn object, so Instance objects also have these operation methods.

jQuery creates a jQuery object every time a query is executed, and in the same application, all jQuery objects share the same jQuery prototype object. Therefore, the jQuery object not only contains the DOM query result set, but also inherits the operation methods on the jQuery prototype object. In this way, you can directly call methods to manipulate these DOM elements after querying. This is the core architecture design of jQuery, which is simple, convenient and practical!

If you still don’t understand the above explanation, don’t worry, I wrote a complete small project jDate according to jQuery’s design ideas, you can compare and understand! The jDate project has been uploaded to GitHub. You can click here to view the complete code: jDate. If you have different opinions, please feel free to discuss!

3 Defects of jQuery

By analyzing the core architecture of jQuery, we will find that every time a query is executed, jQuery will build a complex jQuery in memory Object, although every jQuery object shares the same jQuery prototype, the query process of jQuery is far more complicated than you think. It must consider various matching identifiers and the compatibility of different browsers. Therefore, if you only do some simple operations on the DOM, it is recommended to use the native method querySelector instead of jQuery. However, when using the native method, you may have to do some compatibility work for different application scenarios. You must learn to make trade-offs and not overdo it. Depends on jQuery!

Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

Golang RabbitMQ: Architectural design and implementation of a highly available message queue system Golang RabbitMQ: Architectural design and implementation of a highly available message queue system Sep 28, 2023 am 08:18 AM

GolangRabbitMQ: The architectural design and implementation of a highly available message queue system requires specific code examples. Introduction: With the continuous development of Internet technology and its wide application, message queues have become an indispensable part of modern software systems. As a tool to implement decoupling, asynchronous communication, fault-tolerant processing and other functions, message queue provides high availability and scalability support for distributed systems. As an efficient and concise programming language, Golang is widely used to build high-concurrency and high-performance systems.

Combination practice and architecture design of MongoDB and edge computing Combination practice and architecture design of MongoDB and edge computing Nov 02, 2023 pm 01:44 PM

With the rapid development of the Internet of Things and cloud computing, edge computing has gradually become a new hot area. Edge computing refers to the transfer of data processing and computing capabilities from traditional cloud computing centers to edge nodes of physical devices to improve data processing efficiency and reduce latency. As a powerful NoSQL database, MongoDB is attracting more and more attention for its application in the field of edge computing. 1. Practice of combining MongoDB with edge computing In edge computing, devices usually have limited computing and storage resources. And MongoDB

go-zero architecture design patterns and best practices go-zero architecture design patterns and best practices Jun 22, 2023 pm 12:07 PM

With the rapid development of the Internet, software development has become more and more complex. In order to meet this challenge, software architecture has also continued to evolve, from the initial single application to a microservice architecture. With the popularity of microservice architecture, more and more developers are beginning to adopt gRPC as the communication protocol between microservices. go-zero is a microservices framework based on gRPC. This article will introduce go-zero’s architectural design patterns and best practices. 1. go-zero framework architecture Figure 1: go-zero framework architecture Figure 1

Good Architecture: Using Go Language to Build Highly Scalable Distributed Systems Good Architecture: Using Go Language to Build Highly Scalable Distributed Systems Jun 18, 2023 pm 02:32 PM

As a high-performance programming language, Go language is very popular in the construction of distributed systems. Its high speed and extremely low latency make it easier for developers to implement highly scalable distributed architectures. There are a lot of architectural issues to consider before building a distributed system. How to design an architecture that is easier to maintain, scalable and stable is an important issue faced by all distributed system developers. Using the Go language to build distributed systems can make these architectural choices simpler and clearer. Efficient coroutines The Go language natively supports coroutines.

Architectural design and PHP code implementation of the mall SKU management module Architectural design and PHP code implementation of the mall SKU management module Sep 12, 2023 pm 03:18 PM

Architectural design and PHP code implementation of the mall SKU management module 1. Introduction With the rapid development of e-commerce, the scale and complexity of the mall are also increasing. The SKU (StockKeepingUnit) management module of the mall is one of the core modules of the mall and is responsible for managing the inventory, price, attributes and other information of the products. This article will introduce the architectural design and PHP code implementation of the mall SKU management module. 2. Architecture design Database design The database design of the SKU management module is the foundation of the entire architecture. SKU of the mall

Architectural design based on PHP framework in large projects Architectural design based on PHP framework in large projects Jun 03, 2024 pm 12:34 PM

Large-scale PHP projects can adopt framework-based architectural design, such as layered architecture or MVC architecture, to achieve scalability, maintainability and testability. The layered architecture includes the view layer, business logic layer and data access layer; the MVC architecture divides the application into models, views and controllers. The implementation framework architecture provides a modular design that makes it easy to add new features, reduce maintenance costs, and supports unit testing.

How to design a high-performance PHP microservice architecture How to design a high-performance PHP microservice architecture Sep 24, 2023 pm 04:37 PM

How to design a high-performance PHP microservice architecture. With the rapid development of the Internet, microservice architecture has become the first choice for many enterprises to build high-performance applications. As a lightweight, modular architectural style, microservices can split complex applications into smaller, independent service units, providing better scalability, reliability and maintainability through mutual cooperation. This article will introduce how to design a high-performance PHP microservice architecture and provide specific code examples. 1. Split microservices Before designing a high-performance PHP microservice architecture,

PHP Firewall Implementation: Website Security Architecture Design Guide PHP Firewall Implementation: Website Security Architecture Design Guide Jun 30, 2023 pm 06:57 PM

Website Security Architecture Design Guide: Implementation of PHP Firewall Introduction: In today's Internet era, website security problems are becoming increasingly serious. Hackers are constantly using loopholes to invade websites, steal user information or disrupt the normal operation of the website. In order to protect the privacy and security of the website and its users, it is crucial to establish a reliable security architecture. This article will focus on the implementation of PHP firewall and provide guidance for website security architecture. 1. What is a PHP firewall? The PHP firewall is a security measure that blocks malicious attacks and intrusions by filtering

See all articles