jQuery 原始碼分析

Jhon發表於2017-12-05

這篇文章可以說是讀這篇文章這篇文章後的總結。

jQuery最基本的構成結構:

var jQuery = window.jQuery = window.$ = function(a,b){
  return new jQuery.fn.init(a, b);  // 1
};

jQuery.fn = jQuery.prototype = {
  init: function (s) {
    this[0] = s;
    this.length = 1;
    this.context = s;
    return this;  // 2
  },
  age: function () {
    return this;
  }
};

jQuery.fn.init.prototype = jQuery.fn;  // 3

jQuery.extend = jQuery.fn.extend = function () {
  // 4
}

這是jQuery原始碼一個最基本的概要實現,但從這個實現中已經能弄並學到很多東西了。

( 1 ) 首先 $ 也就是 jQuery 本身是一個函式, 但它又不是一個普通的建構函式,這從 $(`div`) 的這種例項直接產生不需要 new 就可以知道,也就是它隱藏了例項 new 的過程, jQuery 自身只是一個工廠函式,它產出由它的原型上定義的 init 方法的例項,因為擁有了 new 的過程,所以例項化中的 this 都是指向了 最終產生的例項本身,於是這樣便實現了無new構建

( 2 ) 這裡在 init 函式中有一個 return this; 的操作,一般建構函式不會這樣寫,但這樣寫並不會影響 new 的結果,這參照之前new 的分解,便可以推出結果的一致( 只是返回了不同但值相同的變數 )。而jQuery之所以在這裡要返回 this 是有用處的,這樣最開始例項的 this 便得以儲存,$(`div`).ready() 這樣的鏈式呼叫便能得到前方的例項物件,也就是說就是 return this; 實現了鏈式呼叫。

( 3 ) 那既然是原型上的 init 構造器方法構建的例項,又怎麼能獲取到 jQuery 的原型方法呢,這就需要將 init 方法的原型用 jQuery 的原型物件覆蓋。也就是 3 部分的操作。

( 4 ) 最後 $.extend$.fn.extend 之所以會不一樣,只是呼叫時分別是jQuery物件或jQuery.prototype(jQuery.prototype = jQuery.fn)導致了 this 的不同,實際定義是是用的同一個函式。

相關文章