zoukankan      html  css  js  c++  java
  • 【jQuery源码】工具函数

      1 //扩展工具函数
      2 jQuery.extend({
      3     // Unique for each copy of jQuery on the page
      4     expando: "jQuery" + ( version + Math.random() ).replace( /D/g, "" ),
      5 
      6     // Assume jQuery is ready without the ready module
      7     isReady: true,
      8 
      9     error: function( msg ) {
     10         throw new Error( msg );
     11     },
     12 
     13     noop: function() {},
     14 
     15     // See test/unit/core.js for details concerning isFunction.
     16     // Since version 1.3, DOM methods and functions like alert
     17     // aren't supported. They return false on IE (#2968).
     18     isFunction: function( obj ) {
     19         return jQuery.type(obj) === "function";
     20     },
     21 
     22     //首先判断是否支持ES5中的isArray
     23     isArray: Array.isArray || function( obj ) {
     24         return jQuery.type(obj) === "array";
     25     },
     26 
     27     //之前版本是obj && typeof obj === "object" && "setInterval" in obj;
     28     isWindow: function( obj ) {
     29         /* jshint eqeqeq: false */
     30         //window对象是一个包含自己的对象 window.window....window === window;
     31         return obj != null && obj == obj.window;
     32     },
     33 
     34     isNumeric: function( obj ) {
     35         // parseFloat NaNs numeric-cast false positives (null|true|false|"")
     36         // ...but misinterprets leading-number strings, particularly hex literals ("0x...")
     37         // subtraction forces infinities to NaN
     38         // adding 1 corrects loss of precision from parseFloat (#15100)
     39         //当不是数字时,(obj - parseFloat( obj ) + 1)为NaN,所以>=0也就为false
     40         return !jQuery.isArray( obj ) && (obj - parseFloat( obj ) + 1) >= 0;
     41     },
     42 
     43     isEmptyObject: function( obj ) {
     44         var name;
     45         for ( name in obj ) {
     46             return false;
     47         }
     48         return true;
     49     },
     50 
     51     // 检查obj是否是一个纯粹的对象(通过"{}" 或 "new Object"创建的对象)
     52     // console.info( $.isPlainObject( {} ) ); // true
     53     // console.info( $.isPlainObject( '' ) ); // false
     54     // console.info( $.isPlainObject( document.location ) ); // true
     55     // console.info( $.isPlainObject( document ) ); // false
     56     // console.info( $.isPlainObject( new Date() ) ); // false
     57     // console.info( $.isPlainObject( ) ); // false
     58     isPlainObject: function( obj ) {
     59         var key;
     60 
     61         // Must be an Object.
     62         // Because of IE, we also have to check the presence of the constructor property.
     63         // Make sure that DOM nodes and window objects don't pass through, as well
     64         // 必须是一个对象
     65            // 因为在IE8中会抛出非法指针异常,必须检查constructor属性
     66            // DOM节点和window对象,返回false
     67           // obj不存在 或 非object类型 或 DOM节点 或 widnow对象,直接返回false
     68            // 测试以下三中可能的情况:
     69            // jQuery.type(obj) !== "object" 类型不是object,忽略
     70            // obj.nodeType 认为DOM节点不是纯对象
     71            // jQuery.isWindow( obj ) 认为window不是纯对象
     72         if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
     73             return false;
     74         }
     75 
     76         try {
     77             // Not own constructor property must be Object
     78             // 测试constructor属性
     79                // 具有构造函数constructor,却不是自身的属性(即通过prototype继承的)
     80             if ( obj.constructor &&
     81                 !hasOwn.call(obj, "constructor") &&
     82                 !hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) {
     83                 return false;
     84             }
     85         } catch ( e ) {
     86             // IE8,9 Will throw exceptions on certain host objects #9897
     87             return false;
     88         }
     89 
     90         // Support: IE<9
     91         // Handle iteration over inherited properties before own properties.
     92         if ( support.ownLast ) {
     93             for ( key in obj ) {
     94                 return hasOwn.call( obj, key );
     95             }
     96         }
     97 
     98         // Own properties are enumerated firstly, so to speed up,
     99         // if last one is own, then all properties are own.
    100         for ( key in obj ) {}
    101 
    102         return key === undefined || hasOwn.call( obj, key );
    103     },
    104 
    105     type: function( obj ) {
    106         if ( obj == null ) {
    107             return obj + "";//转成字符串的一种方法
    108         }
    109         return typeof obj === "object" || typeof obj === "function" ?
    110             class2type[ toString.call(obj) ] || "object" :
    111             typeof obj;
    112     },
    113 
    114     // Evaluates a script in a global context
    115     // Workarounds based on findings by Jim Driscoll
    116     // http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context
    117     globalEval: function( data ) {
    118         if ( data && jQuery.trim( data ) ) {
    119             // We use execScript on Internet Explorer
    120             // We use an anonymous function so that context is window
    121             // rather than jQuery in Firefox
    122             ( window.execScript || function( data ) {
    123                 window[ "eval" ].call( window, data );
    124             } )( data );
    125         }
    126     },
    127 
    128     // Convert dashed to camelCase; used by the css and data modules
    129     // Microsoft forgot to hump their vendor prefix (#9572)
    130     camelCase: function( string ) {
    131         return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );
    132     },
    133 
    134     //判断节点名称是否相同
    135     nodeName: function( elem, name ) {
    136         return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();
    137     },
    138 
    139     // args is for internal usage only
    140     //遍历对象或数组
    141     each: function( obj, callback, args ) {
    142         var value,
    143             i = 0,
    144             length = obj.length,
    145             isArray = isArraylike( obj );
    146 
    147         //如果有参数
    148         if ( args ) {
    149             if ( isArray ) {
    150                 for ( ; i < length; i++ ) {
    151                     value = callback.apply( obj[ i ], args );
    152 
    153                     if ( value === false ) {
    154                         break;
    155                     }
    156                 }
    157             } else {
    158                 for ( i in obj ) {
    159                     value = callback.apply( obj[ i ], args );
    160 
    161                     if ( value === false ) {
    162                         break;
    163                     }
    164                 }
    165             }
    166 
    167         // A special, fast, case for the most common use of each
    168         //没有参数args则调用,则调用call,上下文设置为当前遍历到的对象,参数设置为key/index和value
    169         } else {
    170             if ( isArray ) {
    171                 for ( ; i < length; i++ ) {
    172                     value = callback.call( obj[ i ], i, obj[ i ] );
    173 
    174                     if ( value === false ) {
    175                         break;
    176                     }
    177                 }
    178             } else {
    179                 for ( i in obj ) {
    180                     value = callback.call( obj[ i ], i, obj[ i ] );
    181 
    182                     if ( value === false ) {
    183                         break;
    184                     }
    185                 }
    186             }
    187         }
    188 
    189         return obj;
    190     },
    191 
    192     // Support: Android<4.1, IE<9
    193     //利用正则去掉前后空格
    194     trim: function( text ) {
    195         return text == null ?
    196             "" :
    197             ( text + "" ).replace( rtrim, "" );
    198     },
    199 
    200     // results is for internal usage only
    201     makeArray: function( arr, results ) {
    202         var ret = results || [];
    203 
    204         if ( arr != null ) {
    205             if ( isArraylike( Object(arr) ) ) {//伪数组
    206                 jQuery.merge( ret,
    207                     typeof arr === "string" ?
    208                     [ arr ] : arr
    209                 );
    210             } else {//不是数组也不是伪数组
    211                 push.call( ret, arr );
    212             }
    213         }
    214 
    215         return ret;
    216     },
    217 
    218     //在数组中搜索指定的值,并返回其索引值,i为查找的起始位置
    219     inArray: function( elem, arr, i ) {
    220         var len;
    221 
    222         if ( arr ) {
    223             if ( indexOf ) {// 是否有本地化的Array.prototype.indexOf
    224                 return indexOf.call( arr, elem, i );
    225             }
    226 
    227             len = arr.length;
    228             i = i ? i < 0 ? Math.max( 0, len + i ) : i : 0;
    229 
    230             for ( ; i < len; i++ ) {
    231                 // Skip accessing in sparse arrays
    232                 //i in arr表示arr[i]存在
    233                 if ( i in arr && arr[ i ] === elem ) {
    234                     return i;
    235                 }
    236             }
    237         }
    238 
    239         return -1;
    240     },
    241 
    242     //将数组second合并到数组first中
    243     merge: function( first, second ) {
    244         var len = +second.length,
    245             j = 0,
    246             i = first.length;
    247 
    248         while ( j < len ) {
    249             first[ i++ ] = second[ j++ ];
    250         }
    251 
    252         // Support: IE<9
    253         // Workaround casting of .length to NaN on otherwise arraylike objects (e.g., NodeLists)
    254         //在IE9以前,类数组对象的length为NaN
    255         if ( len !== len ) {
    256             while ( second[j] !== undefined ) {
    257                 first[ i++ ] = second[ j++ ];
    258             }
    259         }
    260 
    261         first.length = i;
    262 
    263         return first;
    264     },
    265 
    266     // 过滤数组,返回新数组;callback返回true时保留;如果inv为true,callback返回false才会保留
    267     grep: function( elems, callback, invert ) {
    268         var callbackInverse,
    269             matches = [],
    270             i = 0,
    271             length = elems.length,
    272             callbackExpect = !invert;
    273 
    274         // Go through the array, only saving the items
    275         // that pass the validator function
    276         //遍历数组,将回调函数返回值push到结果数组
    277         for ( ; i < length; i++ ) {
    278             callbackInverse = !callback( elems[ i ], i );
    279             if ( callbackInverse !== callbackExpect ) {
    280                 matches.push( elems[ i ] );
    281             }
    282         }
    283 
    284         return matches;
    285     },
    286 
    287     // arg is for internal usage only
    288     //将数组或对象elems的元素/属性,转化成新的数组
    289     map: function( elems, callback, arg ) {
    290         var value,
    291             i = 0,
    292             length = elems.length,
    293             isArray = isArraylike( elems ),
    294             ret = [];
    295 
    296         // Go through the array, translating each of the items to their new values
    297         if ( isArray ) {//类数组或数组
    298             for ( ; i < length; i++ ) {
    299                 value = callback( elems[ i ], i, arg );
    300 
    301                 if ( value != null ) {
    302                     ret.push( value );
    303                 }
    304             }
    305 
    306         // Go through every key on the object,
    307         } else {//对象
    308             for ( i in elems ) {
    309                 value = callback( elems[ i ], i, arg );
    310 
    311                 if ( value != null ) {
    312                     ret.push( value );
    313                 }
    314             }
    315         }
    316 
    317         // Flatten any nested arrays
    318         // 使嵌套数组变平
    319         // concat:
    320         // 如果某一项为数组,那么添加其内容到末尾。
    321         // 如果该项目不是数组,就将其作为单个的数组元素添加到数组的末尾。
    322         return concat.apply( [], ret );
    323     },
    324 
    325     // A global GUID counter for objects
    326     guid: 1,
    327 
    328     // Bind a function to a context, optionally partially applying any
    329     // arguments.
    330     // 代理方法:为fn指定上下文(即this)
    331     proxy: function( fn, context ) {
    332         var args, proxy, tmp;
    333 
    334         //如果context是字符串格式,fn为fn[context]
    335         //上下文环境设为fn
    336         if ( typeof context === "string" ) {
    337             tmp = fn[ context ];
    338             context = fn;
    339             fn = tmp;
    340         }
    341 
    342         // Quick check to determine if target is callable, in the spec
    343         // this throws a TypeError, but we will just return undefined.
    344         // 快速测试fn是否是可调用的(即函数)
    345         // 但是这里仅返回undefined
    346         if ( !jQuery.isFunction( fn ) ) {
    347             return undefined;
    348         }
    349 
    350         // Simulated bind
    351         args = slice.call( arguments, 2 );//从列表中去除前两个参数,即fn,context
    352         proxy = function() {
    353             return fn.apply( context || this, args.concat( slice.call( arguments ) ) );
    354         };
    355 
    356         // Set the guid of unique handler to the same of original handler, so it can be removed
    357         proxy.guid = fn.guid = fn.guid || jQuery.guid++;
    358 
    359         return proxy;
    360     },
    361 
    362     now: function() {
    363         return +( new Date() );
    364     },
    365 
    366     // jQuery.support is not used in Core but other projects attach their
    367     // properties to it so it needs to exist.
    368     support: support
    369 });
  • 相关阅读:
    2017.08.07 python爬虫实战之使用代理爬取糗事百科
    2017.08.05 Python网络爬虫实战之获取代理
    2017.08.04 Python网络爬虫之Scrapy爬虫实战二 天气预报的数据存储问题
    2017.08.04 Python网络爬虫之Scrapy爬虫实战二 天气预报
    2017.07.28 Python网络爬虫之爬虫实战 重新梳理------今日影视爬虫(使用Scrapy爬取ajax动态页面)
    2017.07.28 Python网络爬虫之爬虫实战 今日影视2 获取JS加载的数据
    RabbitMQ之工作队列
    pt-online-schema-change和默认值关系
    flex词法解析
    Makefile持续学习二
  • 原文地址:https://www.cnblogs.com/shytong/p/5315677.html
Copyright © 2011-2022 走看看