`

读jQuery源码之整体框架分析

阅读更多

  读一个开源框架,大家最想学到的就是设计的思想和实现的技巧。最近读jQuery源码,记下我对大师作品的理解和心得,跟大家分享,权当抛砖引玉。

 

先附上jQuery的代码结构。

 

 

Js代码 复制代码 收藏代码
  1. (function(){   
  2.     //jQuery变量定义   
  3.     var jQuery  = function(){...};   
  4.     //jQuery原型定义(包含核心方法)                 
  5.     jQuery.fn = jQuery.prototype = {...};   
  6.     //看上去很奇怪吧? 非常巧妙的设计,后面详细介绍   
  7.     jQuery.fn.init.prototype = jQuery.fn;   
  8.     //提供jQuery静态方法与对象方法的扩展函数   
  9.     jQuery.extend = jQuery.fn.extend = function(){...};    
  10.     //后面依次有多个对jQuery静态方法的扩展   
  11.     jQuery.extend({...});   
  12.     //后面依次有多个对jQuery对象方法的扩展   
  13.     jQuery.fn.extend({...});   
  14.     jQuery.support = (function() {...})();   
  15.     //提供统一时间管理,jQuery内部使用,并不对外开放   
  16.     jQuery.event = {...};   
  17.     //Event类似于Java的POJO类.传递事件的对象   
  18.     jQuery.Event = function( src, props ) {...};    
  19.     //Sizzle选择器,一个框架,可独立使用。   
  20.     (function(){   
  21.         ...   
  22.         jQuery.find = Sizzle;   
  23.         ...   
  24.     })();   
  25.     ...   
  26.     //将定义的jQuery定义为全局变量   
  27.     window.jQuery = window.$ = jQuery;   
  28.     ...   
  29. })();  
(function(){
    //jQuery变量定义
    var jQuery  = function(){...};
    //jQuery原型定义(包含核心方法)              
    jQuery.fn = jQuery.prototype = {...};
    //看上去很奇怪吧? 非常巧妙的设计,后面详细介绍
    jQuery.fn.init.prototype = jQuery.fn;
    //提供jQuery静态方法与对象方法的扩展函数
    jQuery.extend = jQuery.fn.extend = function(){...}; 
    //后面依次有多个对jQuery静态方法的扩展
    jQuery.extend({...});
    //后面依次有多个对jQuery对象方法的扩展
    jQuery.fn.extend({...});
    jQuery.support = (function() {...})();
    //提供统一时间管理,jQuery内部使用,并不对外开放
    jQuery.event = {...};
    //Event类似于Java的POJO类.传递事件的对象
    jQuery.Event = function( src, props ) {...}; 
    //Sizzle选择器,一个框架,可独立使用。
    (function(){
        ...
        jQuery.find = Sizzle;
        ...
    })();
    ...
    //将定义的jQuery定义为全局变量
    window.jQuery = window.$ = jQuery;
    ...
})();

 

 

 

在结构上非常的清晰,定义一个jQuery对象,对jQuery对象进行扩展,赋给window,变成全局变量。就以下几点做介绍:

1). 自执行的匿名函数。

2). $("...")形式调用返回 jQuery.fn.init对象。

3). 框架里最常见的 extend 函数。

 

一. 自执行匿名函数。

对javascript有一定基础的都应该知道自执行匿名函数的好处。js是函数作用域。在函数里定义的变量都是局部变量,这样就很好的避免了过多的全局变量(jQuery仅仅2个全局变量jQuery和$)。由于闭包属性,虽然函数自执行结束了,但自执行函数里面定义的局部函数和变量还是能够被定义成全局变量的jQuery和$所引用到,类似于Java的私有变量。好处可见一斑。

 

二. $("...")形式调用返回 jQuery.fn.init对象。

这是我刚看源码的时候最不理解的地方。

 

Js代码 复制代码 收藏代码
  1. var jQuery = function( selector, context ) {   
  2.     // The jQuery object is actually just the init constructor 'enhanced'   
  3.     return new jQuery.fn.init( selector, context, rootjQuery );   
  4. }   
  5. 和   
  6. jQuery.fn.init.prototype = jQuery.fn;  
var jQuery = function( selector, context ) {
    // The jQuery object is actually just the init constructor 'enhanced'
    return new jQuery.fn.init( selector, context, rootjQuery );
}
和
jQuery.fn.init.prototype = jQuery.fn;
看懂这段我们先看看jQuery的使用。jQuery采用链式调用(如:$("#id").data("xxx")),这样就知道$("#id")返回的是一个jQuery对象。但是调用的方式是函数调用。这个问题就成为了:以函数的方式调用返回jQuery对象,并且构造函数是init。现在就围绕解决这个问题展开:
首先想到的是在函数式调用的时候返回一个jQuery对象。
Js代码 复制代码 收藏代码
  1. var jQuery = function( selector, context ) {   
  2.     return new jQuery( selector, context);   
  3. }  
var jQuery = function( selector, context ) {
    return new jQuery( selector, context);
}
兄弟,你确定这样? 明眼人一看就知道严重的问题所在,死递归!
既然不能调用本身,那我们想到另一种办法:再定义一个函数A,A的原型与jQuery的原型一样,那A的对象与jQuery生成的对象就是一模一样了(javascript是原型继承),而且将A的constructor定义为jQuery,上面的问题不是迎刃而解么?
 
Js代码 复制代码 收藏代码
  1. var jQuery = function( selector, context ) {   
  2.     return new A( selector, context);   
  3. }   
  4.   
  5. var A = function(){   
  6.     if(this.init) {   
  7.         this.init();   
  8.     }   
  9. };   
  10. A.prototype = jQuery.prototype;  
var jQuery = function( selector, context ) {
    return new A( selector, context);
}

var A = function(){
    if(this.init) {
        this.init();
    }
};
A.prototype = jQuery.prototype;

这样就解决了上面的问题,因为jQuery和A拥有同一个原型,所以生成的对象都拥有相同的方法。但是还是感觉A定义的有些多余,是不是?
既然定义A就为了返回A的对象,那init函数也能生成对象(以为js中没有类,定义的函数可以当函数执行,也能new成对象)。既然用init的话,那样init函数会自动执行,也不用再调用,岂不是更方便!所以就看到了我们之前看到的代码。
这里可能还有个fn解释下,其实这个fn没有什么特殊意思,只是jQuery.prototype的引用,jQuery支持自己扩展属性,这个对外提供了一个接口,jQuery.fn.extend()来对对象增加方法,比使用jQuery.prototype.extend()更好。封装想,字面就能看懂是对函数扩展,而不是看上去直接修改prototype.友好的用户接口。
相对于文字,图形化更加直观,对上面的引用来引用去画了个图,更好的理解:


其实在使用返回 new jQuery.fn.init( selector, context, rootjQuery ) 对象方式,我还有另一种实现
Js代码 复制代码 收藏代码
  1. var jQuery = function( selector, context ) {   
  2.     //如果以$("#id") 方式调用this就不是jQuery.这样返回jQuery对象   
  3.     if(!(this instanceof jQuery)) {   
  4.         return new jQuery(selector, context);   
  5.     }   
  6.     if(this.init) {   
  7.         this.init();   
  8.     }   
  9. }   
  10. //这行就可以注释了   
  11. //jQuery.fn.init.prototype = jQuery.fn;  
var jQuery = function( selector, context ) {
    //如果以$("#id") 方式调用this就不是jQuery.这样返回jQuery对象
    if(!(this instanceof jQuery)) {
        return new jQuery(selector, context);
    }
    if(this.init) {
        this.init();
    }
}
//这行就可以注释了
//jQuery.fn.init.prototype = jQuery.fn;
 
这种经过测试时可以的,不知道还有没有其他的隐蔽问题,暂时没发现,也算是一种实现吧。供大家参考。
三. 框架里最看到的 extend 函数
在后面的段落中有大段大段的 jQuery.extend({...}) 和 jQuery.fn.extend({...}) 代码。这里先解释下这个的作用和不同。
extend 在java中是继承,在我之前写的一篇 <简单实现Javascrip继承> 文章不同,也都是用了extend关键字。那些我们都说叫继承,而这里我更加喜欢叫扩展。为什么呢? 继承是产生了新的类,而这里没有,这里的2个函数第一个是扩展jQuery的静态方法,而第二个是用户自己扩展对象的方法。静态方法?对象方法?这里我来做个解释,在jQuery中有2中调用形式:
1)$.Ajax(...);
2)$("#id").data("xxx");
第一种调用我称为静态调用,就类似于Java的静态方法一样,不用生成对象,而是类级函数。这里的$就相当于命名空间一样。我们知道在以往js的编程中,如果有命名空间我们都这样:
var ns = {};
ns.Ajax = function(){...};
那为什么这里不是对象,而是函数做一个命名空间呢? 其实在js中一切都是对象!包括函数也是对象(说Java一切都是对象,我觉得其实这句话形容js更加贴切)。
第二种调用我成为对象调用,因为.data()方法是定义在原型中的,只有new个对象才能调用的,所以成为对象方法。
我们看代码jQuery.extend = jQuery.fn.extend = function(){...}; 这个是连等,也就是2个指向同一个函数,怎么会实现不同的功能呢?这就是this 的功能了。jQuery.extend 调用的时候,this是指向jQuery对象的(jQuery是函数,也是对象!),所以这里扩展在jQuery上。 而jQuery.fn.extend 调用的时候,this指向fn对象,而上图中科院看到,jQuery.fn 和jQuery.prototype指向同一对象,扩展fn就是扩展jQuery.prototype原型对象。这里增加的是原型方法,也就是对象方法了。所以jQuery的api中提供了以上2中扩展函数。
本章结束,有不对和不准确的地方望大家指正。有疑问可以留言。
下篇介绍jQuery的data实现。欢迎关注。
分享到:
评论

相关推荐

    jQuery源码分析之Callbacks详解

    在深入讨论jQuery源码中Callbacks模块的内部实现之前,先要明确什么是Callbacks以及它在JavaScript编程中的作用。Callbacks,即回调函数,在JavaScript中扮演着至关重要的角色。由于JavaScript是基于单线程事件循环...

    jQuery源码+中文详细注解

    ### jQuery源码+中文详细注解 #### 一、引言 本文档是对jQuery源码进行中文注解的详细介绍,旨在帮助广大前端开发者更深入地理解jQuery的核心逻辑和技术要点。通过对核心部分的逐行注解,可以更好地掌握jQuery的...

    jquery源码 带格式

    通过以上对jQuery源码的部分分析,我们可以看出jQuery在设计上考虑了兼容性、性能以及安全性,采用了大量的正则表达式进行字符串和DOM元素的处理,并提供了丰富的工具函数和API来简化JavaScript的编程工作。

    SSH+Jquery 源码(含数据库)

    SSH框架是Java Web开发中常用的一套高效、轻量级的整合框架,用于构建企业级的MVC(Model-View-Controller)应用。而jQuery则是JavaScript库,简化了DOM操作、事件处理和动画制作,极大地提高了前端开发效率。 **...

    Jquery源码分析

    《jQuery源码分析》 jQuery,作为一款广泛使用的JavaScript库,极大地简化了DOM操作、事件处理、动画制作以及Ajax交互。对于深入理解JavaScript和前端开发技术的开发者来说,探究jQuery的源码是提升技能的重要途径...

    JQuery源码详细中文注释!

    JQuery源码的详细中文注释是为帮助开发者深入理解JQuery的内部机制,提高编程技能,同时也能帮助有志于深入研究JavaScript的人士更加清晰地了解JQuery的运行原理。 JQuery源码以一个自执行匿名函数的形式存在,这...

    jQuery 2.0.3 源码分析之core(一)整体架构

    在深入探讨jQuery 2.0.3源码中core部分的整体架构之前,我们先简要回顾一下jQuery框架的核心功能和其设计思想。jQuery是一个广泛使用的JavaScript库,主要用于简化HTML文档遍历和操作、事件处理、动画和Ajax交互。它...

    [精华]网站论坛源码C# Jquery,完全自制,有很多jquery自己写的插件

    此源码可以作为学习C# ASP.NET和Jquery结合开发的实例,帮助开发者了解如何在实际项目中整合这两种技术。通过阅读和分析这些源码,可以提升对于Web应用架构设计、数据库交互、前后端通信以及客户端脚本优化的理解。...

    jquery-easyui-1.3.5 源码

    `1.3.5` 是这个框架的一个版本,我们接下来将深入探讨其核心概念、主要功能以及源码分析。 1. **jQuery EasyUI 核心概念** - **jQuery**:EasyUI 基于 jQuery 构建,jQuery 是一个快速、简洁的JavaScript库,用于...

    json jquery simple tree 源码

    开发者可以参考这个资源来学习如何在自己的项目中整合JSON和jQuery Simple Tree。 总的来说,"json jquery simple tree 源码"提供了一种高效、灵活的方法,使得jQuery Simple Tree能够利用JSON数据进行异步加载,...

    jQuery bootstrap响应式系统框架

    **jQuery Bootstrap响应式系统框架详解** 在Web开发领域,jQuery和Bootstrap是两个广泛使用的工具,它们结合在一起构建出的响应式后台系统框架,为开发者提供了高效、便捷的开发环境。本篇文章将深入探讨jQuery和...

    html左右侧框架源码

    在"html左右侧框架源码"中,左侧菜单通常使用`&lt;ul&gt;`和`&lt;li&gt;`元素构建一个层次结构,可能结合JavaScript或jQuery实现动态展开与折叠的效果,以便于展现树形架构。为了实现交互性,开发者可能会使用事件监听(如`click...

    webjars_jquery源码.rar

    在这个"webjars_jquery源码.rar"压缩包中,包含了对jQuery库的打包以及一个Web测试项目。 首先,jQuery是一个广泛使用的JavaScript库,它极大地简化了DOM操作、事件处理、动画制作以及Ajax交互。jQuery的核心特性...

    jQuery+EasyUI开发指南源码

    通过深入研究这份源码,开发者不仅可以提升jQuery和EasyUI的技能,还能了解到Web应用开发的整体流程和设计模式,对于构建现代企业级Web应用具有重要的参考价值。无论你是初学者还是有经验的开发者,都能从中受益匪浅...

    jQuery Gantt官方源码

    9. **扩展与集成**:jQuery Gantt可能与其他库(如Bootstrap、AngularJS等)兼容,以便于整合到现有的Web框架中。此外,还可以通过编写自定义插件或扩展来增加新的功能。 10. **性能优化**:对于大型项目,加载和...

    JQuery核心源码_全套1.5_2.0.2

    《jQuery核心源码详解——从1.5到2.0.2的演进之路》 jQuery,这个被誉为“JavaScript库的王者”,自2006年发布以来,因其简洁易用的API和强大的...现在,就让我们一起打开这份珍贵的资源,踏上jQuery源码探索之旅吧!

    jquery源码

    《jQuery源码解析》 jQuery,作为一款广泛应用于前端开发的JavaScript库,以其简洁的API、强大的功能和良好的浏览器兼容性赢得了开发者们的喜爱。深入理解jQuery的源码,不仅可以提升我们的编程技能,还能帮助我们...

    jquery easyui demo和源码

    源码分析可以帮助开发者理解EasyUI如何处理事件、渲染DOM元素、以及与jQuery的交互方式,对于性能优化和扩展功能很有价值。 ### 演示示例 (`jquery-easyui-DEMO`) `jquery-easyui-DEMO` 文件夹提供了各种组件的使用...

    JQuery Mobile权威指南+附书源码+中文api

    jQuery Mobile 是一个用于构建响应式网页和移动应用的框架,它基于 jQuery 库,专注于提供一致且易用的用户界面,适用于多种设备,包括智能手机、平板电脑以及桌面浏览器。jQuery Mobile 的核心理念是“Write less, ...

    jquery-starterkit源码

    "jQuery-starterkit源码"是一套为初学者和开发者提供的基础框架,旨在帮助他们快速理解和构建基于jQuery的Web应用。这份资料包含了必要的文件和代码示例,以便于深入学习和实践。 首先,`ratings.dat`可能是一个...

Global site tag (gtag.js) - Google Analytics