Home > Web Front-end > JS Tutorial > Talk about jQuery core architecture design

Talk about jQuery core architecture design

PHPz
Release: 2018-09-28 15:20:03
Original
1211 people have browsed it

jQuery對於大家而言並不陌生,因此關於它是什麼以及它的作用,在這裡我就不多言了,而本篇文章的目的是想透過對源碼簡單的分析來討論jQuery 的核心架構設計,以及jQuery 是如何利用javascript中的高階特性來建立如此偉大的javascript函式庫。

1 初識jQuery

從核心功能來看,jQuery只做了一件簡單而又平凡的事:查詢。它的文法如此簡潔明了,以致於很多人在不知道javascript是什麼的時候就已經會用jQuery了,用一個字形容就是:大道至簡。 

從設計層面來看,我們可以將jQuery提供方法分為兩大類:靜態方法和實例方法。靜態方法就是直接透過$存取的方法,這些方法一般不對dom元素操作,而是提供了一些常用的工具,例如ajax請求、以及對字串的一些常用操作,除此之外,jQuery還提供了對自身的擴充機制,你可以透過extend方法來寫你需要的元件。而實例方法和靜態方法不一樣,它是用來對jQuery查詢的DOM元素進行操作,jQuery執行$()會建構一個jQuery對象,這個對像以數組的方法存儲查詢出的所有DOM元素,然後在這個在物件的原型鏈上實作了對這些DOM操作的方法,例如each()方法就是用來遍歷每一個DOM元素的。

你可能會注意到,我剛說這個物件「以數組的方式」存儲,那就是說,jQuery建構的這個物件不是數組,那這個物件到底是什麼? 其實這個物件就是jQuery的核心,也被稱為「jQuery物件」。因此,本文的重點就是對jQuery物件進行分析與討論。

2 jQuery物件

一般情況下,我們會這樣使用jQuery:

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

$('div')執行完後回傳回一個jQuery對象,each()方法是對這個物件中的DOM元素進行遍歷,我們先來看看$('div')的執行過程(本文源碼摘自jQuery 3.0):

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

}
Copy after login

這個方法就是$('div')的入口方法,$是jQuery的簡寫,就相當於jQuery('div') ,可以看出,這個方法只做了一件事,那就是返回jQuery.fn.init ()函數的實例對象,那jQuery.fn.init 又是什麼呢,我們再看下面的程式碼:

init = jQuery.fn.init = function( selector, context, root ) {
 //... 
 return this;
}
init.prototype = jQuery.fn;
Copy after login

jQuery.fn.init和init引用了同一個方法,這個方法根據selector查詢出符合條件的DOM元素,並返回,可你會發現,返回的是this,這個this是什麼呢?我們待會分析,先看下面的這句話:

init.prototype = jQuery.fn;
這句話是什麼意思呢,這句話是讓init方法的prototype對象指向了jQuery.fn對象,那jQuery.fn又是什麼鬼? 我們繼續看程式碼:

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

為了節省篇幅,我省略了其中一些程式碼,從這裡可以看出,jQuery.fn 其實就是jQuery的原型對象,這個原型對象定義了一些對this物件進行操作的方法。到這裡,你是不是感覺到有點繞,不要著急,我們來梳理一下思路:jQuery首先定義了一個init方法,然後在init的原型對象prototype上定義了一系列操作方法。最後將init方法的實例物件傳回。所以上面的過程可以簡化如下(偽代碼表示):

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

那麼問題來了,jQuery.fn中的方法為什麼不直接定義在init的prototype上,而要定義在jQuery的原型對像上?

其實,這樣做的目的是為了提高jQuery的查詢效率,如果直接定義在init的prototype對像上,那麼每執行一次查詢,就會在內存中創建這樣一個龐大的prototype對象,而如果把這個物件定義在jQuery的prototype上,在jQuery載入時,這個物件就會被初始化並且一直存在於記憶體中,以後每次執行$()時,只需要將init中的prototype指向這個物件就可以了,而不用每次都去創建一遍相同的物件。

我們再來看看init 函數中傳回的this 到底是什麼,我在之前的部落格中講過,函數中的this總是指向運行期的呼叫者,那init的呼叫者是誰呢?在上面程式碼中似乎找不到呼叫者,這時我們就需要深入的理解new運算子的運作機制了,借用我之前在部落格中對new運算子的描述,我們對new init()的執行過程進行如下分解:

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

As can be seen from the above decomposition process, when JavaScript creates an instance object through new, it will first create an ordinary 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, all matched DOM objects will be stored in the this object in the form of an array and returned, that is, the obj object will be returned, and the new operator will eventually return this obj object. Returned as a new instance object. Therefore, 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 the instance object also Have these methods of operation.

jQuery will create a jQuery object every time it executes a query, and in the same application, all jQuery objects will 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 must 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 are just doing 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!

The above is the entire content of this article. I hope it will inspire everyone to learn jquery. For more related tutorials, please visit jQuery Video Tutorial!

source:php.cn
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
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template