$().find().css().hide()
從jQuery的表達式能夠看出兩點:css
下面從這兩方面來窺探jQuery的總體架構:html
這一點是推測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後期在討論。