搜尋
首頁web前端js教程淺談 jQuery 核心架構設計

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 ...});

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

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

}

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

init = jQuery.fn.init = = jQuery.fn;

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
};

為了節省篇幅,我省略了其中一些程式碼,從這裡可以看出,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);
}

那麼問題來了,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;

}

從上述分解過程可以看出,javascript在透過new 來創建一個實例對象的時候,會先創建了一個普通對象obj,然後將obj的內部屬性__proto__指向了init的原型對象,因此obj的原型鏈將被改變,而第3步使用call方法呼叫init(),所以init中的this指的就是這裡的obj物件。

init()執行以後,會將匹配到的所有DOM對像以數組的方式存儲到this對像中並返回,也就是返回了obj對象,而new運算符最終也會將這個obj 對象返回以作為新的實例物件。 所以new運算子回傳的這個實例物件具備兩個特點:一是包含了DOM查詢結果集,二是其原型鏈繼承了init的prototype,而init 的prototype 又指向了jQuery.fn對象,因此實例對象也具備了這些操作方法。

jQuery每執行一次查詢就會建立一個jQuery對象,而在同一個應用程式中,所有jQuery物件都會共用同一個jQuery原型物件。因此,jQuery物件不僅包含了DOM查詢結果集,也繼承了jQuery原型物件上的操作方法。這樣,你就可以在查詢後直接呼叫方法來操作這些DOM元素了。這就是jQuery的核心架構設計,簡單、方便、實用!

如果你還不理解上面的講解,不要著急,我按照jQuery的設計思路寫了一個完整的小項目jDate,你可以對比著理解! jDate專案已上傳至GitHub,你可以點擊這裡查看完整程式碼:jDate ,如有不同見解,歡迎討論!

3 jQuery 的缺陷

透過對jQuery的核心架構分析,我們會發現,每執行一次查詢,jQuery就要在內存中構建一個複雜的jQuery對象,雖然說每個jQuery對像都共享同一個jQuery原型,但jQuery的查詢過程遠比你想像的要複雜,它既要考慮各種不同的匹配標識,同時又要考慮不同瀏覽器的兼容性。因此,如果你只是對DOM做一些簡單的操作,建議使用原生方法querySelector 替代jQuery,不過在使用原生方法時,對於不同的應用場景你可能要做一些兼容性的工作,你要學會取捨,不要過度依賴jQuery!

陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
MongoDB与边缘计算的结合实践与架构设计MongoDB与边缘计算的结合实践与架构设计Nov 02, 2023 pm 01:44 PM

随着物联网和云计算的快速发展,边缘计算逐渐成为新的热点领域。边缘计算是指将数据处理和计算能力从传统的云计算中心转移到物理设备的边缘节点上,以提高数据处理的效率和减少延迟。而MongoDB作为一种强大的NoSQL数据库,其在边缘计算领域的应用也越来越受到关注。一、MongoDB与边缘计算的结合实践在边缘计算中,设备通常具有有限的计算和存储资源。而MongoDB

Golang RabbitMQ: 实现高可用的消息队列系统的架构设计和实现Golang RabbitMQ: 实现高可用的消息队列系统的架构设计和实现Sep 28, 2023 am 08:18 AM

GolangRabbitMQ:实现高可用的消息队列系统的架构设计和实现,需要具体代码示例引言:随着互联网技术的不断发展和应用的广泛,消息队列成为了现代软件系统中不可或缺的一部分。作为一种实现解耦、异步通信、容错处理等功能的工具,消息队列为分布式系统提供了高可用性和扩展性的支持。而Golang作为一种高效、简洁的编程语言,广泛应用于构建高并发和高性能的系统

良好架构:使用Go语言构建高扩展性分布式系统良好架构:使用Go语言构建高扩展性分布式系统Jun 18, 2023 pm 02:32 PM

作为一款高性能的编程语言,Go语言在分布式系统的建设中非常流行。它的高速度和极低的延迟时间让开发人员更加容易实现高扩展性的分布式架构。在构建分布式系统前,需考虑的架构问题非常繁琐。如何设计出更加易于维护、可扩展和稳定的架构是所有分布式系统开发者面临的重要问题。使用Go语言来构建分布式系统,可以使这些架构选择变得更加简单和明晰。高效的协程Go语言天生支持协程,

大型项目中基于PHP框架的架构设计大型项目中基于PHP框架的架构设计Jun 03, 2024 pm 12:34 PM

大型PHP项目可采用基于框架的架构设计,如分层架构或MVC架构,以实现可扩展性、可维护性和可测试性。分层架构包括视图层、业务逻辑层和数据访问层;MVC架构将应用程序划分为模型、视图和控制器。实施框架架构可提供模块化设计,便于添加新功能、降低维护成本并支持单元测试。

go-zero架构设计模式及最佳实践go-zero架构设计模式及最佳实践Jun 22, 2023 pm 12:07 PM

随着互联网的迅猛发展,软件开发变得越来越复杂。为了应对这一挑战,软件架构也不断演进,从最初的单体应用,到微服务架构。而随着微服务架构的普及,越来越多的开发者开始采用gRPC作为微服务之间的通信协议。go-zero就是一套基于gRPC构建的微服务框架。本文将介绍go-zero的架构设计模式及最佳实践。一、go-zero框架架构图1:go-zero框架架构如图1

商城SKU管理模块的架构设计与PHP代码实现商城SKU管理模块的架构设计与PHP代码实现Sep 12, 2023 pm 03:18 PM

商城SKU管理模块的架构设计与PHP代码实现一、引言随着电子商务的迅猛发展,商城的规模和复杂性也日益增加。商城的SKU(StockKeepingUnit)管理模块是商城的核心模块之一,负责管理商品的库存、价格、属性等信息。本文将介绍商城SKU管理模块的架构设计和PHP代码实现。二、架构设计数据库设计SKU管理模块的数据库设计是整个架构的基础。商城的SKU

如何设计一个高性能的PHP微服务架构如何设计一个高性能的PHP微服务架构Sep 24, 2023 pm 04:37 PM

如何设计一个高性能的PHP微服务架构随着互联网的快速发展,微服务架构成为了许多企业构建高性能应用的首选。作为一种轻量级、模块化的架构风格,微服务可以将复杂的应用拆分成更小的、独立的服务单元,通过相互协作提供更好的扩展性、可靠性和可维护性。本文将介绍如何设计一个高性能的PHP微服务架构,并提供了具体的代码示例。一、拆分微服务在设计高性能的PHP微服务架构之前,

基于Go语言的微服务架构设计与实现基于Go语言的微服务架构设计与实现Nov 20, 2023 pm 01:08 PM

随着云计算和容器化技术的快速发展,微服务架构已经成为了构建大型分布式系统的首选架构之一。微服务架构的核心理念是将复杂的单体应用拆分成一系列小而独立的服务,通过轻量级的通信方式进行交互,从而提高系统的可伸缩性、可靠性和可维护性。而Go语言作为一种简洁高效的编程语言,被广泛应用于微服务架构的实现当中。本文将介绍基于Go语言的微服务架构设计与实现的关键要点。一、微

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
2 週前By尊渡假赌尊渡假赌尊渡假赌
倉庫:如何復興隊友
4 週前By尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island冒險:如何獲得巨型種子
3 週前By尊渡假赌尊渡假赌尊渡假赌

熱工具

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

SAP NetWeaver Server Adapter for Eclipse

SAP NetWeaver Server Adapter for Eclipse

將Eclipse與SAP NetWeaver應用伺服器整合。

mPDF

mPDF

mPDF是一個PHP庫,可以從UTF-8編碼的HTML產生PDF檔案。原作者Ian Back編寫mPDF以從他的網站上「即時」輸出PDF文件,並處理不同的語言。與原始腳本如HTML2FPDF相比,它的速度較慢,並且在使用Unicode字體時產生的檔案較大,但支援CSS樣式等,並進行了大量增強。支援幾乎所有語言,包括RTL(阿拉伯語和希伯來語)和CJK(中日韓)。支援嵌套的區塊級元素(如P、DIV),

Atom編輯器mac版下載

Atom編輯器mac版下載

最受歡迎的的開源編輯器