学习源码第三天(短暂的坚持)

/* 给JQuery原型添加属性和方法 */
  jQuery.fn = jQuery.prototype = {
    // The current version of jQuery being used
    jquery: core_version,  //版本

    constructor: jQuery,   //添上constructor 指向构造函数,修复constructor
    init: function(selector, context, rootjQuery) {
      var match, elem;

      // HANDLE: $(""), $(null), $(undefined), $(false)
      if (!selector) {
        return this;
      }

      // Handle HTML strings
      if (typeof selector === 'string') {
        if (
          selector.charAt(0) === '<' &&
          selector.charAt(selector.length - 1) === '>' &&
          selector.length >= 3
        ) {
          // Assume that strings that start and end with <> are HTML and skip the regex check
          match = [null, selector, null];
        } else {
          match = rquickExpr.exec(selector);
        }

由这段代码可知,jQuery.fn就是jQuery.prototype,现在要把jQuery的原型重写,重写一定会破坏constructor指向jQuery的这个构造函数,所以要手动添加;小写的jquery是版本号

var jq = new Jquery()
console.log(jq.jquery) // 2.0.3

接下来是重点的init,没错就是那个不像构造函数的init

init: function(selector, context, rootjQuery) {
      var match, elem;

      // HANDLE: $(""), $(null), $(undefined), $(false)
      if (!selector) {
        return this;
      }

selector参数是选择器字符串,其他两个参数暂且不论,然后定义了match,elem;紧接着来了一个if语句,if(!selector)的意思就是selector为“”,null,undefined,false对应的情况注释给我们了HANDLE: $(""), $(null), $(undefined), $(false) 处理四种获取不到的情况,jQuery里面直接去return this;不但终止了下列代码的执行,还返回了this,这个this就是jQuery.prototype

// Handle HTML strings
      if (typeof selector === 'string') {
        if (
          selector.charAt(0) === '<' &&                     /*   chatAt(下标)截取对应下标字符的意思
          selector.charAt(selector.length - 1) === '>' &&    *   这3句判断了selector字符串是不是长<a>或<aaa>的总之要有一个尖括号,而且尖括号里面必须有字符
          selector.length >= 3                               */  这句话并不能保证像<1>这种的
        ) {
          // Assume that strings that start and end with <> are HTML and skip the regex check
          match = [null, selector, null];
        } else {
      //除了<a>、<1>这种的,例如<aa>、<aa>11,返回的要么selector不满足rquickExpr正则匹配规则的null,要么返回一个数组
      //如果是<aa>11这种返回的match = [ <aa>11,<aa>,undefined ],意思是把<aa>11这种的解析为<aa>,容错性增加
match
= rquickExpr.exec(selector); }
//正则.exec()返回一个数组或null,如果 exec() 找到了匹配的文本,则返回一个结果数组。否则,返回 null。此数组的第 0 个元素是与正则表达式相匹配的文本,第 1 个元素是与 RegExpObject 的第 1 个子表达式(正则1|正则2)相匹配的文本(如果有的话),第 2 个元素是与 RegExpObject 的第 2 个子表达式(正则1|正则2)相匹配的文本(如果有的话)
 

这一段是如果$()括号里面不是上述四种的情况,那么就是一个有值的字符串。再进入一个if...else if语句(这里截取的是if里面嵌套的if else语句),如果selector是一个字符串类型,那么就可以再判断他是不是一个标签类似于'<a>',三个字符尖括号开头和结尾,如果类似这种就把[null,selector,unll]这样一个数组赋值给前面定义的match,否则,match就会等于rquickExpr.exec(selector);

那么这是什么意思呢?正则的exec()方法返回的是一个数组,那么这个数组长什么样呢?上面已经定了rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,这就涉及到正则,简单的说下:

 

/^$/是精确匹配的意思 
?: 不储存(非贪婪匹配),以后\1引用不了,如果后面不引用,这样做可以减少内存
\s是空白符 *出现0或多次 \s*空白符出现0或多次
(<[\w\W]+>)---()表示储存起来以后可以引用,有可能不在本正则表达式引用\w 是字母,数字,下划线,小提醒一下:字母不单单是英文字母,俄文字母也行哦\W是除去\w的情况,+是出现一次以上
[^>]* 不是'>'的0次或多次 类似于<aa>这种 或<aa>11这种
|#([\w-]*) 或者'#'后匹配任意数字字符下划线- 出现0次或以上   #的情况或#aaa这种

 

rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/ 匹配了'<aa>'、'<a>11'、'#'、'#111'这种字符串。match = [null, selector, null]是反映'<1>'、'<a>'尖括号内一个字符的情况;而match = rquickExpr.exec(selector);①反映'<aa>'、'<aa>11'、'#122'、'#'这种情况等等(也就是在rquickExpr匹配的范围内 - 尖括号内一个字符的情况 ),②甚至包括了requickExpr匹配范围之外的情况'11<aa>'、'abc'、'123'这种不符合requickExpr匹配规则的,这时候通过exec方法,如果符合匹配规则(①的情况),返回一个数组,数组的三个元素第一个是匹配的文本,第二个是与第一个子表达式匹配的文本,第三个是与第二个表达式匹配的文本;如果不符合(②的情况),match通过exec方法返回null。
顺带一提:\s*的作用是像$('    <div>')一样可以有多个空格。容错性真的好!

 

posted @ 2019-04-23 00:07  火鸡的呐喊  阅读(143)  评论(0编辑  收藏  举报