拜读jquery源码(一)

    xiaoxiao2021-03-25  139

    之前有前辈和我说学习JavaScript的知识点,尤其是比较抽象和深奥的点,可以看下优秀的框架源码,所以今天开始拜读jquery的源码,不仅是巩固jquery的用法和每个方法的实现,更重要的是学习框架的设计模式以及设计缘由。

    借鉴和参考别人的理解:

    jQuery的总体框架:  (function(window,undefined){     var jQuery=function(selector,context){         //...     };     //工具方法utilities     //回调函数 callbacks     //异步队列 Defered Object     //浏览器功能测试 Support     //数据缓存 Data     //队列 Queue     //属性操作 Attributes     //事件系统 Events     //选择器 Sizzle     //DOM遍历 Traversing     //DOM操作 Manipulation     //样式操作 CSS     //异步请求  Ajax     //动画 Animation     //坐标 offset,尺寸 Dimensions     window.jQuery=window.$=jQuery; }})(window); 关于上述代码,解释如下: 1.jQuery的整体代码包裹在一个立即执行的自调用匿名的函数中,这样可以尽量减少和其他第三方库的干扰; 2,在上述代码最后,将jQuery对象添加到全局window上,并为之设置变量$,从而使得可以在外界访问jQuery; 3,为自调用匿名函数设置参数window,并传入参数window,这样一方面可以缩短作用域链,可以尽快访问到window;另一方面便于代码压缩; 4,为自动用匿名函数设置参数undefined,一方面可以缩短查找Undefined的作用域链,另一方面可防止undefined在外界被修改。

    jquery.fn执行jquery的原型对象,共享方法,让我们更好理解,jQuery是一个封装得非常好的‘类’,比如我们用语句 $("#btn1") 会生成一个 jQuery类的实例。

    以下是阅读后做的笔记,其中难以理解的是pushStack 方法,pushStack() 函数用于将一个DOM元素集合加入到jQuery栈, 主要是用于内部函数。

    //jquery.fn执行jquery的原型对象 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, //toArray:取回包含在该jquery集合中的所有元素,作为一个数组 //alert( $( "li" ).toArray() );调用这个方法,所有的匹配的DOM节点都会返回,包含在一个标准数组中:[<li id="foo">, <li id="bar">] //arr.slice.call(this),call方法调用一个对象的一个方法,以另一个对象替换当前对象。 //this是jquery.fn的实例,toArray方法完全继承了slice的方法和属性 toArray: function() { return slice.call( this ); }, // Get the Nth element in the matched element set OR // Get the whole matched element set as a clean array //get方法没有参数则返回所有元素的一个数组,同toArray方法 //有参数则取回jquery对象所匹配的DOM元素,例如console.log( $( "li" ).get( 0 ) );=><li id="bar"> get: function( num ) { // Return all the elements in a clean array if ( num == null ) { return slice.call( this ); } // Return just the one element from the set //console.log( $( "li" )[ 0 ] );的句法无法用负数索引,负索引从匹配元素的末尾开始计数 //num为负数则转换为正数,get(-1)=>get(2) return num < 0 ? this[ num + this.length ] : this[ num ]; }, // Take an array of elements and push it onto the stack // (returning the new matched element set) //pushStack把获取的元素数组放到栈中返回一个新的被匹配的数组 //在执行jquery构造函数之后会产生一个实例对象,里面放着匹配到的元素,当使用这一个方法时 //就会再新建一个空的jquery对象,然后再把调用这个方法的对象匹配到的元素放到栈中,就是一 //个数组通过一个指针指向调用此方法的对象,这样就是一个链式栈可以不断扩展 pushStack: function( elems ) { // Build a new jQuery matched element set //构造一个新的空jquery对象ret,this.constructor 指向构造函数 jQuery() //$.merge() 函数用于合并两个数组内容到第一个数组 var ret = jQuery.merge( this.constructor(), elems ); // Add the old object onto the stack (as a reference) //在新对象中添加这么一个属性来指向当前的jQuery对象 //merge产生的jQuery对象设置一个prevObject属性,并将当前(merge之前的)的对象赋值给prevObject ret.prevObject = this; // Return the newly-formed element set return ret; }, // Execute a callback for every element in the matched set. //迭代一个jQuery对象,针对每个匹配的元素执行一个函数 /*例如: $( "li" ).each(function( index ) { console.log( index + ": " + $( this ).text() ); }); */ each: function( callback ) { return jQuery.each( this, callback ); }, //将一组数组转换为其他数组 map: function( callback ) { return this.pushStack( jQuery.map( this, function( elem, i ) { return callback.call( elem, i, elem ); } ) ); }, slice: function() { return this.pushStack( slice.apply( this, arguments ) ); }, first: function() { return this.eq( 0 ); }, last: function() { return this.eq( -1 ); }, eq: function( i ) { //若i=-1,len=3,则j=0+3=3,即最后一位索引为-1,第一位索引为0 var len = this.length, j = +i + ( i < 0 ? len : 0 ); return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] ); }, //end返回当前jquery对象的上一个状态 // 所有通过pushStack方法获得的jQuery对象都可以通过end方法返回之前的状态   // 如果有preObject对象则返回该对象,否则调用构造函数返回jQuery的空对象 end: function() { return this.prevObject || this.constructor(); }, // For internal use only. // Behaves like an Array's method, not like a jQuery method. //javascript原生方法 push: push, sort: arr.sort, splice: arr.splice };

    转载请注明原文地址: https://ju.6miu.com/read-3175.html

    最新回复(0)