视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
jquery源码的基本介绍
2020-11-27 19:34:02 责编:小采
文档


(令: jquery从2.0之后就不兼容IE 6/7/8 了)

一、 总体架构
;(function(global, factory) {
 // 传入window可以将其作为一个局部变量使用,缩短了作用域链,大大加快执行速度
 factory(global);
}(typeof window !== "undefined" ? window : this, function(window, noGlobal) {
 // jquery方法
 var jQuery = function( selector, context ) {
 return new jQuery.fn.init( selector, context );
 };
 // jQuery.fn 是 jquery对象的原型对象
 jQuery.fn = jQuery.prototype = {};
 // 核心方法
 // 回调系统
 // 异步队列
 // 数据缓存
 // 队列操作
 // 选择器引
 // 属性操作
 // 节点遍历
 // 文档处理
 // 样式操作
 // 属性操作
 // 事件体系
 // AJAX交互
 // 动画引擎
 if ( typeof noGlobal === strundefined ) {
 window.jQuery = window.$ = jQuery;
 }

 return jQuery;
}));

关于上述代码,解释如下:

  1. jQuery的整体代码包裹在一个立即执行的自调用匿名的函数中,这样可以尽量减少和其他第三方库的干扰;自动初始化这个函数,让其只构建一次。

  2. 在上述代码最后,将jQuery对象添加到全局window上,并为之设置变量$,从而使得可以在外界访问jQuery;

  3. 为自调用匿名函数设置参数global,并传入参数window,这样一方面可以缩短作用域链,可以尽快访问到window;

  • 自调用函数的原理(立即执行的自调用函数)

  • jQuery使用()将匿名函数括起来,然后后面再加一对小括号(包含参数列表)的目的,简单来说就是小括号括起来后,就当作是一个表达式来处理,得到的就是一个 function 对象了。同时小括号也取得了这个函数的引用位置,然后传入参数就可以直接执行了。总结: 全局变量是魔鬼, 匿名函数可以有效的保证在页面上写入JavaScript,而不会造成全局变量的污染,通过小括号,让其加载的时候立即初始化,这样就形成了一个单例模式的效果从而只会执行一次。
    (function( global, factory ) {
    
     // 因为jquery既要再普通环境下运行,也要再例如AMD、commonJs下运行,所以我们需要做不同的适应
     // node CommonJs规范
     if ( typeof module === "object" && typeof module.exports === "object" ) {
     module.exports = global.document ?
     factory( global, true ) :
     function( w ) {
     if ( !w.document ) {
     throw new Error( "jQuery requires a window with a document" );
     }
     return factory( w );
     };
     } else {
     // AMD
     factory( global );
     }
    
    
     // 传入参数(window和一个执行函数) 
     }(typeof window !== "undefined" ? window : this, function( window, noGlobal ) {
     
     // 【1】
     // 创建jQuery对象, 实际上是jQuery.fn.init所返回的对象
     var jQuery = function( selector, context ) {
     return new jQuery.fn.init( selector, context );
     // 如果调用new jQuery, 生成的jQuery会被丢弃,最后返回jQuery.fn.init对象
     // 因此可以直接调用jQuery(selector, context), 不需要使用new
     // 如果使用new jQuery()容易出现死循环
     // 我们平常使用 $() ,就是直接调用jquery函数了
     }
    
     // 【2】
     // 创建jQuery对象原型,为jQuery添加各种方法
     jQuery.fn = jQuery.prototype = {
     ...
     } 
     
     // 【3】
     // 在调用new jQuery.fn.init后, jQuery.fn.init.prototype = jQuery.fn = jQuery.prototype
     // 相当于将所有jQuery.fn的方法都挂载到一开始jQuery函数返回的对象上
     // 这里就是jquery的一个独特之处了,非常的巧妙
     jQuery.fn.init.prototype = jQuery.fn;
    
     // 【4】
     // 创建jQuery.extend方法
     jQuery.extend = jQuery.fn.extend = function() {、
     ...
     }
     
    
     // 【5】
     // 使用jQuery.extend扩展静态方法
     jQuery.extend({});
    
     // 【6】
     // 为window全局变量添加$对象,在给window全局添加变量的时候很有可可能会导致变量命名冲突哦,我们之后会学习到如何处理这种命名冲突的解决方法
     if ( typeof noGlobal === strundefined ) { // var strundefined = typeof undefined
     window.jQuery = window.$ = jQuery;
     
     // $('')
     // 同 jQuery('')
     }
    
    
     return jQuery;
     }));
    二、 jQuery的类数组对象

    可以这么理解,jquery主要的任务就是获取DOM操作DOM

    jQuery的入口都是通过$()来的,通过传入不同的参数,实现了9种重载方法。

    1. jQuery([selector,[context]])
    2. jQuery(element)
    3. jQuery(elementArray)
    4. jQuery(object)
    5. jQuery(jQuery object)
    6. jQuery(html,[ownerDocument])
    7. jQuery(html,[attributes])
    8. jQuery()
    9. jQuery(callback)
    
    // 9种用法整体来说可以分三大块:选择器、dom的处理、dom加载。
  • 在jquery内部使用了一种类数组对象的形式,这也是为什么我们获取到同一个class的许多DOM后,既能够调用jquery的方法,又能通过数组的方式来处理每一个dom对象了(比如遍历)。

  • 例子喽

    通过$(".Class")构建的对象结构如下所示:\

    <p> 
     <span class="span">1</span>
     <span class="span">2</span>
     <span class="span">3</span>
    </p>
    
    
    
    console.log($('.span'));
    
    // jQuery.fn.init(3) [span.span, span.span, span.span, prevObject: jQuery.fn.init(1), context: document, selector: ".span"]
    // 0:span.span
    // 1:span.span
    // 2:span.span
    // context: document
    // length: 3
    // prevObject: jQuery.fn.init [document, context: document]
    // selector:".span"
    // __proto__:Object(0)
    // 模拟一下
    function Ajquery(selecter) {
     // 如果传入的不是一个对象,则将其转换为对象
     if(!(selecter instanceof Ajquery)) {
     return new Ajquery(selecter);
     }
     var elem = document.getElementById(/[^#].*/.exec(selector)[0]); // 获取id
     this[0] = elem;
     this.length = 1;
     this.context = document;
     this.selector = selector;
     this.get = function(num) {
     return this[num];
     }
     return this;
    }
    
    
    // 使用
    
    $('#show2').append(Ajquery('#book').get(0));
    
    // 因此 $('')获取到的就是一个类数组对象

    jQuery的无new构造原理

    我们在构造jQuery对象的时候,并没有使用new来创建,但其实是在jQuery方法的内部,我们使用了new,这样就保证了当前对象内部就又了一个this对象,并且吧所有的属性和方法的键值对都映射到this上了,所以既可以通过链式取值,也可以通过索引取值。jquery除了实现了类数组结构, 方法的原型共享,还实现了静态和实例的共享.

    javascript就是函数式语言,函数可以实现类,所以javascript不是一个严格的面向对象的语言。

  • 平时的情况

  • function ajquery(name){
     this.name = name;
    }
    ajquery.prototype = function(){
     say: function(){
     return this.name;
     } 
    }
    
    var a = new ajquery();
    
    a.say();
  • 但是在jquery中却不是这么来的。jQuery没有使用new运行符将jQuery显示的实例化,还是直接调用其函数

  • $().ready() 
    $().noConflict()
  • 如果要实现不用new直接获得实例

  • var aQuery = function(selector, context) {
     return new aQuery(); // 直接new一下
    }
    aQuery.prototype = {
     name:function(){},
     age:function(){}
    }
    // 如果是上诉的样子,直接new aQuery()则会导致死循环。
  • 如何得到一个正确的实例呢,那么可以把jQuery类当作一个工厂方法来创建实例,把这个方法放到jQuery.prototye原型中,然后实例化这个方法,从而创建一个实例

  • // 下面就是jquery的写法了
    jQuery = function( selector, context ) {
     return new jQuery.fn.init( selector, context, rootjQuery );
    },
    
    // 但是问题又来了,init中的this指向的是实例init的原型,就导师了jquery类的this分离了,
    // 解决这个问题的方法是:
    
    jQuery.fn.init.prototype = jQuery.fn;

    下载本文
    显示全文
    专题