1. 程式人生 > >學習源碼第四天(昨天只看了一點正則,發現正則真的水很深,但很有魅力)

學習源碼第四天(昨天只看了一點正則,發現正則真的水很深,但很有魅力)

也有 才會 sch col text 方式 tex nodetype 遍歷

第三天主要對match的值做了一個判斷 match[1]要麽是標簽字符串,要麽macth就是null 像<li>、<li>11都轉成‘li‘作為match[1]。

match[1]現在‘<li><li>‘ 或 ‘<li>‘

if (match && (match[1] || !context)) // 判斷 id 是否有環境context限制,只有沒有限制(不寫默認document,這裏的匹配就是不寫第二個參數的情況) $(‘#box‘)

①滿足match有值,即匹配rquickExpr , ② $(‘<li>‘)、$(‘<li>‘,document)、$(‘<li>‘,其他環境如iframe,第三方插件) ,match[1] || ! context 當match[1]存在就是標簽,match[2]存在就是#aa的形式,因為如果if成立match確定存在,當match[2]存在然後滿足context這個環境不存在即可(不存在即默認是在document也就是本文檔中)

我所理解的context : 假如說我在本html頁面的body裏面添加了一個<div id="box">,那麽$(‘#box‘),可以獲取,但是我不在當前html文件創建,我跑到其他html頁面創建,然後通過iframe引進來,這時候$("#box",context),第二個參數context就起作用了(iframe用得不多,所以一般來說context不寫默認document就好),同理在第三方插件中可能也有#box這個id元素。可以說jquery被大家這麽廣為流傳不是沒有原因的,兼顧到了不常用的情況,像iframe在H5都廢棄了。

補充一下:需要了解正則表達式.exec()的朋友:http://www.w3school.com.cn/js/jsref_exec_regexp.asp

 1 if (match[1]) { //創建標簽 -- 
 2             context = context instanceof jQuery ? context[0] : context;
 3 
 4             // scripts is true for back-compat
 5             jQuery.merge(
 6               this,
 7               jQuery.parseHTML(
 8                 match[1],
 9                 context && context.nodeType
? context.ownerDocument || context : document, 10 true 11 ) 12 );

if (match[1]) 不是‘#aa’,這種id的情況,是‘<aaa>‘這種情況尖括號開頭結尾

context = context instanceof jQuery ? context[0] : context; // $(‘<li>‘,$(document))或 $(‘<li>‘,$(‘ul‘)) $(document)[0],原生document就是document,
那麽jquery會從ul下面去找,說通俗點就是一個查找域,經過這行代碼轉變成原生節點,後續需要用到原生DOM對象這一性質,但這一代碼並不能保證無意義的字符串$(‘li‘,‘uu‘),uu在節點
上根本沒有的情況這行代碼不做判斷因為context直接邏輯短路
// 插入script標簽
jQuery.merge(
this, jQuery.parseHTML( match[1], context && context.nodeType ? context.ownerDocument || context : document, true ) );

jQuery.parseHTML()的作用如下:var str = "<li>1</li><li>2</li><li>3</li>";jQuery.parseHTML(str) 返回的數組[li,li,li],每個li都是一個DOM原生對象。

接下來看一下三個參數,一個節點字符串,一個查找域,一個布爾值

match[1]:各種‘< 裏面可以是任意字符 >‘類型

查找域 :context && context.nodeType ? context.ownerDocument || context : document 【此時context已是原生節點】【如果context不存在就是默認document】【如果存在並且是DOM節點的話,context可以是本身也可以是context.ownerDocument屬性一樣的思議】

布爾值:默認是false,true的話處理的是‘<script></script>‘標簽插入的情況,這麽寫不行,如果前面有script標簽,會認為配對所以要轉義‘<script><\/script>‘,然後就算這樣加入到DOM節點還是起不到js效果,只有設置了true才會在DOM節點上起js效果。

然後看jQuery.merge(this,返回的節點數組):this指向jQuery構造函數,將返回的節點數組和this合並要有length屬性,需要和數組的length屬性相加。 這樣的結果就是this中新增了原生的節點,但是卻是用原本對象的最後一個數字屬性名(已經被對象的length截取之後)之後再去拼接的

簡單說說:
如果obj1 = { ‘3‘ : ‘哈哈‘,length : 4} arr = [1,2,3] $.merge(obj1,arr) //代表的就是{ ‘3‘ : ‘哈哈‘,‘4‘:1, ‘5‘:2,‘6‘:3,length : 7}

所以明白了為什麽$()[0]可以拿到原生節點,因為改造了this這個jQuery構造函數的實例

下面是我另寫的一篇關於$.merge()的:https://www.cnblogs.com/wchjdnh/p/10763451.html

// HANDLE: $(html, props)
        //rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>|)$/ ---<aaa></aaa、<aaa />、<aaa /></aaa>這幾種情況 |在當前正則表達式中表明了後面可以沒有
            if (rsingleTag.test(match[1]) && jQuery.isPlainObject(context)) {  //滿足一對標簽或單標簽和 第二個參數是純對象形式 $(‘<li></li>‘,{ title : ‘我是li‘ , html : ‘hh‘,css:{color:‘red‘} })
              for (match in context) {   // 屬性遍歷context,這是對象遍歷match不一定是數字字符串
                // Properties of context are called as methods if possible
                if (jQuery.isFunction(this[match])) {  //判斷this[match]是不是方法
                  this[match](context[match]);  //是方法就調用參數是context[match]的值 ,也就是說$(‘<li></li>‘,{ title : ‘我是li‘ , html : ‘hh‘,css:{color:‘red‘} })中像html,css都是jQuery的方法,那就直接調用 
                  // ...and otherwise set as attributes
                } else {
                  this.attr(match, context[match]); //不是方法作為屬性設置 title不是方法直接處理用設置屬性的方式
                }
              }
            }
return this; //創建標簽結束,因為是創建標簽操作,其他代碼的操作不執行return,創建標簽結束返回的是jQuery對象 比方說
$(‘<li>1</li>‘).appendTo(‘ul‘)返回li的jQuery對象
      // return this是結束創建標簽節點的相關操作 同時return this就是返回工廠函數jQuery(這時候看成工廠函數)創造的this,這個this已經被改造成了有原生DOM節點的jQuery對象實例了

學習源碼第四天(昨天只看了一點正則,發現正則真的水很深,但很有魅力)