zoukankan      html  css  js  c++  java
  • jquery 源码分析六

    以下吐槽:

       最近一直在面试啊找工作啊,然后学校里又有一堆事情,结果看代码的时间变少了。憋了好几天终于感觉可以写一篇文章了,早上就爬起来赶紧写下来,怕又忘了。吐槽下:小本科找工作真的好难。。。。

    正文开始:

    首先是Sizzle里面的一些基础方法,也可是说是用的比较多的东西。因为Sizzle一开始就定义了许许多多的变量,所以这边先讲一些这次会用到的变量(比较简单的。。)

     1     expando = "sizzle" + -(new Date()),
     2     //给每个Sizzle生成一个特征码,区别每个sizzle
     3     preferredDoc = window.document,
     4     //指向document
     5     dirruns = 0,
     6     done = 0,
     7     classCache = createCache(),
     8     tokenCache = createCache(),
     9     compilerCache = createCache(),
    10     //这个制造了一个存储的空间,具体的createCache函数会在下面讲
    11     sortOrder = function( a, b ) {
    12         if ( a === b ) {
    13             hasDuplicate = true;
    14         }
    15         return 0;
    16     },
    17 
    18     // 未定义
    19     strundefined = typeof undefined,
    20     MAX_NEGATIVE = 1 << 31,
    21 
    22     // 定义原生的方法,方便后面快速使用
    23     hasOwn = ({}).hasOwnProperty,
    24     arr = [],
    25     pop = arr.pop,
    26     push_native = arr.push,
    27     push = arr.push,
    28     slice = arr.slice,
    29     // 如果原生的indexOf没有的话,就用自己写得函数
    30     indexOf = arr.indexOf || function( elem ) {
    31         var i = 0,
    32             len = this.length;
    33         for ( ; i < len; i++ ) {
    34             if ( this[i] === elem ) {
    35                 return i;
    36             }
    37         }
    38         return -1;
    39     },

    注意:这里的代码都是在开头var里面截取出来的,所以后面都是逗号。。。

    下面是关于createCache(),createCache返回的是一个function,这个函数接受两个参数,分别是key,value。key值会存入keys 数组中,然后value会放到这个函数作为object形式的相应key值下,具体代码如下:

     1 function createCache() {
     2     var keys = [];
     3 
     4     function cache( key, value ) {
     5         // 用key+ " "来防止覆盖原生的一些方法
     6         if ( keys.push( key + " " ) > Expr.cacheLength ) {
     7             //若超过数量限制,就把最前面的一些数弹出
     8             delete cache[ keys.shift() ];
     9         }
    10         return (cache[ key + " " ] = value);
    11     }
    12     return cache;
    13 }

     接下来是一些正则表达式,备份正则表达式还没理解,所以有注释的只是其中部分:

     1     //用于检测空格符,包括回车之类的
     2     whitespace = "[\x20\t\r\n\f]",
     3     // 检测由\.或字符-或非ASCII从00到a0的值
     4     characterEncoding = "(?:\\.|[\w-]|[^\x00-\xa0])+",
     5 
     6     // 这个还没理解,英文翻译了也没看懂。。但是应该是用来匹配css的
     7     // 一个未被应用的值应该是css标识符http://www.w3.org/TR/css3-selectors/#attribute-selectors
     8     // Proper syntax: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier
     9     identifier = characterEncoding.replace( "w", "w#" ),
    10 
    11     // 用来匹配attribute的,有点长。。。
    12     attributes = "\[" + whitespace + "*(" + characterEncoding + ")" + whitespace +
    13         "*(?:([*^$|!~]?=)" + whitespace + "*(?:(['"])((?:\\.|[^\\])*?)\3|(" + identifier + ")|)|)" + whitespace + "*\]",
    14 
    15     // Prefer arguments quoted,
    16     //   then not containing pseudos/brackets,
    17     //   then attribute selectors/non-parenthetical expressions,
    18     //   then anything else
    19     // These preferences are here to reduce the number of selectors
    20     //   needing tokenize in the PSEUDO preFilter
    21     pseudos = ":(" + characterEncoding + ")(?:\(((['"])((?:\\.|[^\\])*?)\3|((?:\\.|[^\\()[\]]|" + attributes.replace( 3, 8 ) + ")*)|.*)\)|)",
    22 
    23     // 检测字符串首尾空白符用的
    24     rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\])(?:\\.)*)" + whitespace + "+$", "g" ),
    25         //用来检测逗号前后的空白的
    26     rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ),
    27     rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ),
    28 
    29     rattributeQuotes = new RegExp( "=" + whitespace + "*([^\]'"]*?)" + whitespace + "*\]", "g" ),
    30 
    31     rpseudo = new RegExp( pseudos ),
    32     ridentifier = new RegExp( "^" + identifier + "$" ),
    33         //根据不同的属性建立不同的正则,后面可以分离检测不同的css selector部分
    34     matchExpr = {
    35         "ID": new RegExp( "^#(" + characterEncoding + ")" ),
    36         "CLASS": new RegExp( "^\.(" + characterEncoding + ")" ),
    37         "TAG": new RegExp( "^(" + characterEncoding.replace( "w", "w*" ) + ")" ),
    38         "ATTR": new RegExp( "^" + attributes ),
    39         "PSEUDO": new RegExp( "^" + pseudos ),
    40         "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\(" + whitespace +
    41             "*(even|odd|(([+-]|)(\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace +
    42             "*(\d+)|))" + whitespace + "*\)|)", "i" ),
    43         "bool": new RegExp( "^(?:" + booleans + ")$", "i" ),
    44         // 用于 .is()
    45         "needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\(" +
    46             whitespace + "*((?:-\d)?\d*)" + whitespace + "*\)|)(?=[^-]|$)", "i" )
    47     },
    48         //input类型检测
    49     rinputs = /^(?:input|select|textarea|button)$/i,
    50     rheader = /^hd$/i,
    51         //是否有原生代码
    52     rnative = /^[^{]+{s*[native w/,
    53 
    54     // 快速简单的检测ID TAG CLASS
    55     rquickExpr = /^(?:#([w-]+)|(w+)|.([w-]+))$/,
    56 
    57     rsibling = /[+~]/,
    58     rescape = /'|\/g,
    59 
    60     // 没搞懂。。。CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters
    61     runescape = new RegExp( "\\([\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ),
    62     funescape = function( _, escaped, escapedWhitespace ) {
    63         var high = "0x" + escaped - 0x10000;
    64         // NaN means non-codepoint
    65         // Support: Firefox
    66         // Workaround erroneous numeric interpretation of +"0x"
    67         return high !== high || escapedWhitespace ?
    68             escaped :
    69             high < 0 ?
    70                 // BMP codepoint
    71                 String.fromCharCode( high + 0x10000 ) :
    72                 // Supplemental Plane codepoint (surrogate pair)
    73                 String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );
    74     };

    还有一段关于push那些NodeList的bug修复,在Android小于4.0的浏览器中,push会静默的失败,所以为了兼容这个,就需要写一个自己的push方法,jquery代码如下:

    try {
        push.apply(
            (arr = slice.call( preferredDoc.childNodes )),
            preferredDoc.childNodes
        );
        // 检测Android<4.0
        // push静默的失败,下面这句会抛出错误
        arr[ preferredDoc.childNodes.length ].nodeType;
    } catch ( e ) {
        push = { apply: arr.length ?
    
            // 尽量使用原生的push
            function( target, els ) {
                push_native.apply( target, slice.call(els) );
            } :
    
            // 对于IE9
            // 用自己的方法,直接添加到后面
            function( target, els ) {
                var j = target.length,
                    i = 0;
                // 需要自己设置length,length不可靠
                while ( (target[j++] = els[i++]) ) {}
                target.length = j - 1;
            }
        };
    }

    下一篇会分析的是Sizzle比较核心的代码,已经看了一大部分了,会尽快发上来,不会拖延很长时间的(谁来拯救我的拖延症。。)

  • 相关阅读:
    java并发初探CountDownLatch
    java并发LockSupport
    java并发初探ReentrantWriteReadLock
    mysql视图初探
    mysql索引
    java并发AtomicIntegerFieldUpdater
    php7.* 新特性
    搜索引擎 对比
    2021-03-09 吐槽
    linux 进程&线程
  • 原文地址:https://www.cnblogs.com/cyITtech/p/3597875.html
Copyright © 2011-2022 走看看