2013-03-09 192 views
8

jQuery如何允許其構造函數作爲接受參數的函數來使用,同時它的構造函數也可以作爲接受參數的函數?jQuery原型和構造函數鏈接

我對JavaScript有點新,所以請原諒,如果這是一個noob問題,(我已經看過源代碼但很難嘗試解剖)。

無論如何,作爲示例$(document).ready(<args>);構造函數$()和原型ready()充當函數。怎麼樣?因爲如果我試試這個:

var $ = function(selector) { 
    if(selector == document) { 
     return document; 
    } 
}; 

$.prototype = { 
    constructor: $, 
    ready: function(args) { 
     if(isDomReady) { 
      args.apply(document); 
     } else { 
      window.onload = args; 
     } 
    } 
}; 

var isDomReady = (document.addEventListener || document.readyState == ("complete"|"loaded"|true|4) || document.onreadystatechange()) ? true : false; 

$(document).ready(function() { alert("Wibbles!") }); 

我得到一個錯誤遺漏的類型錯誤:對象[對象全局]有沒有方法「準備好」

+0

你不是通過'ready'返回'this'來鏈接方法。 – 2013-03-09 05:03:57

+1

我知道你爲什麼會收到錯誤消息。 $(document)只是返回沒有.ready函數的HTMLDocument。如果$有一個「元素」屬性,它在運行構造函數時存儲了文檔元素,那麼您可以通過訪問ready函數中的存儲元素來檢查它的就緒狀態。 – MattDiamant 2013-03-09 05:04:19

+0

@MattDiamant Ahh ......我想我會重讀幾次這篇評論供學習。大聲笑。但我想我明白了。謝謝。 – 2013-03-09 05:08:05

回答

8

你知道,這很吸引了我。你已經接受了一個答案,但讓我只是發佈我的,如果它證明有用。有一個fiddle created here

jQuery = function(selector, context) { 
    // The jQuery object is actually just the init constructor 'enhanced' 
    return new jQuery.fn.init(selector, context); 
}; 

jQuery.fn = jQuery.prototype = { 
    constructor: jQuery, 
    context: null, 
    isReady: null, 
    init: function(selector, context) { 
     if (selector === document){ 
      this.context = document; 
      this.selector = document; 
     } 
     console.log(this); 
     return this; 
    }, 
    ready: function(func){ 
     var args = Array.prototype.slice.call(this, arguments), 
      boundReadyFunc = func.bind(this, args.slice(1)); 

     if (this.isReady){ 
      func(); 
     } 
     else { 
      document.addEventListener("DOMContentLoaded", this.onReady.bind(this, func), false); 
     } 
    }, 
    onReady: function(func){ 
     console.log("onready"); 
     this.isReady = true; 
     func.call(this); 
    }, 
}; 

jQuery.fn.init.prototype = jQuery.fn; 
jQuery(document).ready(function(){ 
    alert("Hey, here I am"); 
}); 

讓我試着解釋這是如何工作的。

每次調用類似$(selector)時,都會創建一個新的jQuery實例,並提供您提供的選項(請參閱return new jQuery.fn.init(selector, context););

爲了方便起見,我們將jQuery原型公開爲另一個全局名爲jQuery.fn。爲了使其真正可鏈接,init函數必須返回一個新的jQuery實例。這就是爲什麼在最後我們明確定義jQueryjQuery.init的原型是相同的。這樣,你現在可以連鎖函數調用,如

$(document).ready(DoSomethingHere) 

希望這會有所幫助。

另外,您可以在github上找到jQuery源代碼。它是模塊化的,很容易遵循。

+0

謝謝!這更多的是我正在尋找的方向,但是有點晚了,我已經進入了功能鏈。不過謝謝! – 2013-03-09 17:35:51