zoukankan      html  css  js  c++  java
  • jQuery 源码分析5: jQuery 基本静态方法(一)

    jQuery在初始化过程中会为自己扩展一些基本的静态方法和属性,以下是jQuery 1.11.3版本 239 ~ 564行间所扩展的静态属性和方法

     
      1 jQuery.extend({
      2 
      3 // 为每个jQuery拷贝建立一个唯一的编号
      4 expando: "jQuery" + ( version + Math.random() ).replace( /D/g, "" ),
      5  
      6 // 假设jQuery脱离模块支持,已经准备好
      7 isReady: true,
      8 
      9 // 空转函数
     10 noop: function() {},
     11 
     12 /******************* 基本类型判断方法 *****************************/
     13 
     14 isFunction: function( obj ) {
     15      return jQuery.type(obj) === "function";
     16 },
     17 isArray: Array.isArray || function( obj ) {
     18      return jQuery.type(obj) === "array";
     19 },
     20 isWindow: function( obj ) { /* jshint eqeqeq: false */
     21      return obj != null && obj == obj.window;
     22 },
     23 
     24 isNumeric: function( obj ) {
     25 // 首先抛弃数组, 利用parseFloat返回一个浮点数
     26 // 如果obj是一个合法数字(包括字符串数字),与parseFloat返回值的差是0,因此相减后等0,于是加1
     27 // 如果obj是"0x10",返回值则是0,而obj - 0则会得到16,因此判断"0x10"也是数值
     28 // 如果obj是"abc"等非法数字,会得到NaN - NaN,最终也会得到非数值的判断
     29 
     30      return !jQuery.isArray( obj ) && (obj - parseFloat( obj ) + 1) >= 0;
     31 },
     32  // 保证obj不包含任何属性
     33 isEmptyObject: function( obj ) {
     34      var name;
     35      for ( name in obj ) {
     36 
     37           return false;
     38      }
     39      return true;
     40 },
     41 // 最常使用的判断之一,纯对象判断
     42 // 纯对象是有 new 或 {} 创建的对象
     43 // 意味着纯对象不能从其他对象原型中继承而来,只能从Object原型中继承
     44 isPlainObject: function( obj ) {
     45      var key;
     46      // 首先必须是一个object
     47      // 针对IE,需要检查对象的constructor属性
     48      // 把DOM节点和window对象都过滤掉
     49      if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
     50           return false;
     51      }
     52       try {
     53           // Not own constructor property must be Object
     54           if ( obj.constructor &&                      // 不包含构造器
     55                !hasOwn.call(obj, "constructor") &&
     56                !hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) {
     57                return false;
     58           }
     59 
     60      } catch ( e ) {
     61           // IE8或9在某些主机上会抛出异常
     62           return false;
     63      }
     64       // 支持: IE<9
     65      // 先处理继承的属性,之后才会处理自身属性
     66      if ( support.ownLast ) {
     67           for ( key in obj ) {
     68                return hasOwn.call( obj, key );
     69           }
     70      }
     71      // 一般浏览器是先遍历自己的属性,因此利用空变量来略过之前的自身属性,直接跳到最后一个属性
     72      // 如果最后一个属性是自身的,那么证明了所有属性都是自身的
     73      for ( key in obj ) {}
     74      return key === undefined || hasOwn.call( obj, key );
     75 },
     76 
     77  
     78 
     79 /********************** 基本工具 **********************/
     80 
     81 type: function( obj ) {
     82      if ( obj == null ) {
     83           return obj + "";          // 返回一个字符串 'null'
     84      }
     85 
     86      // //jQuery初始化过程中会产生一个"class到type"的表
     87      // jQuery.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function(i, name) {
     88      //      class2type[ "[object " + name + "]" ] = name.toLowerCase();
     89      // });
     90      // // 实际上class2type是这样的
     91      // var class2type = {
     92      //      "[object Array]": "array",
     93      //      "[object Boolean]": "boolean",
     94      //      "[object Date]": "date",
     95      //      "[object Function]": "function",
     96      //      "[object Number]": "number",
     97      //      "[object Object]": "object",
     98      //      "[object RegExp]": "regexp",
     99      //      "[object String]": "string",
    100      //      "[object Error]" : "error",
    101      // };
    102      // toString(123) 实际上会返回一个字符串"[object Number]",此时就可以通过class2type表来返回"number"
    103      // type(123) 返回的就是"number"
    104      // 这样做的原因是,对于很多对象,typeof返回的只是object,无法区分具体是什么对象
    105      // 通过object.prototype.toString.call(obj),虽然可以判断出什么对象,但是返回值却不够简练,因此使用了class2type进行映射
    106    return typeof obj === "object" || typeof obj === "function" ?
    107             class2type[ toString.call(obj) ] || "object" :     // 通过class2type来返回object类型
    108             typeof obj;
    109 },
    110  // Evaluates a script in a global context
    111 // 在全局上下文上执行一个脚本
    112 globalEval: function( data ) {
    113      if ( data && jQuery.trim( data ) ) {
    114           // IE上使用execScript
    115           // 使用一个匿名函数,从而使上下文在firefox中变成window而非jQuery
    116           ( window.execScript || function( data ) {
    117                window[ "eval" ].call( window, data );
    118           } )( data );
    119      }
    120 },
    121 // 转换 dashed to camelCase; CSS和数据模块才使用这个方法
    122 // 首先要去除'-ms-'中的第一个'-'
    123 // 然后删除'-'并将'-'后紧接着的字母转换成大写
    124 // rmsPrefix = /^-ms-/
    125 // rdashAlpha = /-([da-z])/gi
    126 // fcamelCase = function( all, letter ) {
    127 //          return letter.toUpperCase();
    128 // };
    129 camelCase: function( string ) {
    130      return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );
    131 },
    132 // 判断elem节点的名字是否为name
    133 // 在后面对节点的操作经常会用到
    134 nodeName: function( elem, name ) {
    135      return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();
    136 },
    137 });
    总结
    • 基本判断方法里,jQuery.isNumeric的实现过程比较简练,要判断"0x10"这样的十六进制数字,又要判断"1.23"这样的浮点数.该方法里面只使用到了parseFloat,并根据其返回值的特点("字符串前部的合法数字"),只使用一次函数就可判别出数字,实现得非常精明;
    • 纯对象的判断jQuery.isPlainObject也是用得较多的工具,其中针对浏览器的兼容性实现和优化都值得学习;
    • jQuery.type的实现方案更加精彩,因此不同平台上typeof不一定能够准确返回对象的类型,因此需要使用到Object.ptototype.toString方法,然而这个方法会返回不需要的字符,建立一个映射表便可解决这一个问题;
  • 相关阅读:
    HTML DOM 06 节点关系
    HTML DOM 05 事件(三)
    HTML DOM 05 事件(二)
    HTML DOM 05 事件(一)
    html DOM 04 样式
    html DOM 03 节点的属性
    html DOM 02 获取节点
    html DOM 01 节点概念
    JavaScript 29 计时器
    JavaScript 28 弹出框
  • 原文地址:https://www.cnblogs.com/elcarim5efil/p/4673098.html
Copyright © 2011-2022 走看看