2013-03-09 25 views
8

jQueryは、そのコンストラクタが引数を受け入れる関数としてどのように機能するのか、そのコンストラクタは引数を受け入れる関数としても機能しますか?jQueryのプロトタイプとコンストラクタ関数の連鎖

JavaScriptについて少し慣れているので、これがノブの質問であれば私は言い訳をします(私はソースを見てきましたが、解剖しようとするのは難しいです)。

とにかく、例として$(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!") }); 

を私はエラーにキャッチされない例外TypeError取得:オブジェクトを[グローバルオブジェクト]は、それが機能連鎖と呼ばれるプログラミング技法だ

+0

あなたは 'ready'から' this'を返すことでメソッドを連鎖させません。 –

+1

エラーメッセージが表示される理由を知っています。 $(document)は.ready関数を持たないHTMLDocumentを返すだけです。 $がコンストラクタの実行時にドキュメント要素を格納した "element"プロパティを持っていれば、ready関数内の格納された要素にアクセスすることで準備状態を確認できます。 – MattDiamant

+0

@MattDiamant Ahh ...私は勉強のためにそのコメントを数回読み返すだろうと思う。笑。しかし、私は理解していると思う。ありがとう。 –

答えて

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) 

これは役に立ちます。

さらに、jQueryのソースはgithubにあります。これはモジュラーで、とても簡単です。

+0

ありがとう!これは私が探していたより多くの方向ですが、少し遅れてしまいました。私はすでに機能連鎖に入りました。ありがとう、しかし! –

関連する問題