jQuery源碼學習(1):總體架構

總體架構

$().find().css().hide()

從jQuery的表達式能夠看出兩點:css

  1. jQuery的構建方式
  2. jQuery的調用方式

下面從這兩方面來窺探jQuery的總體架構:html

 

分析一:無new構建

這一點是推測jQ構建方式的重點。既然沒有使用new,jQ一定在函數中返回了一個實例,也就是經過工廠模式來建立對象。jquery

var aQuery = function(select){
  var o = new Object();
  o.select = select;
  o.myFunc = function(){};
}

然而這種方法顯然很是笨拙,每次新建一個對象實例都必須聲明其全部共用方法。能不能把構造函數與原型模式融入到這裏面來呢?架構

var aQuery = function(selector){
  return aQuery.prototype.init(selector);
};

aQuery.prototype = {                                  // aQuery的原型
  init: function(selector){                  // init做爲新的構造函數
    this.selector = selector;
return this; }, myFunc: function(){} }; console.log(aQuery('s1'));

代碼運行以後,在控制檯顯示的是下面這樣的結果:異步

{ 
  init: [Function],
  myFunc: [Function],
  selector: 's1'
}

this指向了aQuery的原型對象,而且共用了全部方法。然而這裏面的陷阱在於,因爲咱們並無new一個新對象,因此構造函數內部的this指向了aQuery的原型,共享了本應該私有的屬性。ide

var a1 = aQuery('s1');
var a2 = aQuery('s2');
console.log(a1.selector);      // s2

那麼是否是隻要返回一個新實例就能夠了呢?函數

var aQuery = function(selector, context){
  return (new aQuery.prototype.init(selector, context));
};

aQuery.prototype = {...};

var a1 = aQuery('s1');
var a2 = aQuery('s2');
console.log(a1.selector);      // s1
console.log(a1);         //{ selector: 's1' }   myFunc不見了!

由上可見,new關鍵字新建了一個空對象,使構造函數內部的this指向該對象,解決了屬性公有的問題(這部分知識點請參考Javascript對象部分)。然而同時,也丟失了aQuery.prototype。那麼jQuery是怎麼解決這個問題的呢?這就是jQuery構建方法的關鍵所在:原型傳遞。源碼分析

直接上代碼:this

var aQuery = function(selector){
  return (new aQuery.prototype.init(selector));
};

aQuery.prototype = {                                  // aQuery的原型
  init: function(selector){                  // init做爲新的構造函數
    this.selector = selector;
    return this;
  },
  myFunc: function(){
    return "aQuery.func";
  }
};
aQuery.prototype.init.prototype = aQuery.prototype;

var a1 = aQuery('s1');
var a2 = aQuery('s2');
console.log(a1.selector);      // s1
console.log(a1.myFunc());      // aQuery.func

其實本質上講,init構建出來的這個對象,就是jQuery對象。spa

這樣,咱們總算理清了jQuery無new構建的原理。使用工廠模式返回一個實例,並將該實例構造函數的原型指向aQuery原型自己,實現了私有屬性和共有方法。

 

各中關係如圖所示,其中fn指代了jQuery的原型對象。

 

分析二:鏈式調用

當使用了new關鍵字後,jQuery的全部方法中的this都指向了新建的實例,因此咱們只要在方法最後返回this,就能夠實現鏈式調用。然而:

摘自Aaron的JQ源碼分析

最糟糕的是全部對象的方法返回的都是對象自己,也就是說沒有返回值,這不必定在任何環境下都適合。


Javascript是無阻塞語言,因此他不是沒阻塞,而是不能阻塞,因此他須要經過事件來驅動,異步來完成一些本須要阻塞進程的操做,這樣處理只是同步鏈式,異步鏈式jquery從1.5開始就引入了Promise,jQuery.Deferred後期在討論。

相關文章
相關標籤/搜索