jquery的構造函數很好的運用的javascript的充分利用了JavsScript語言的動態性——對行參的類型和個數沒有的嚴格要求,以至於一個函數可以實現多種功能需求,也為JavaScript語言的多態性提供了基礎,在這個構造函數中,提供了六種不同的調用格式(根據官方API文檔)
在我的上一篇文章裡面 闡述了jQuery的大致框架,知道了所有代碼都是寫在了一個自調用匿名函數裡面,並且傳入了window對象,源碼是這樣的:
?
1 (function( window, undefined ) {...})( window );我們通過alert(jquery) 知道它是一個對象,那麼這個對象是怎麼構造出來的呢?我們使用$(document)類似的寫法獲取元素,就好像直接調用了普通的方法一樣,jQuery就是普通的函數嗎?如果是構造函數為什麼不是 new $(document)的常見形式呢?
其實jQuery是面向對象js庫,也有構造函數,每次調用jQuery方法是就會實例化一個jQeury對象,但是jQuery的寫法卻非常高明。
首先先談談js面向對象: js雖然不是面向對象的語言,卻又很多面向對象的寫法,這裡推薦大家看一下圖靈的《javascript高級程序設計》中的面向對象的程序設計部分。在眾多方法中比較常使用的寫法是構造加原型方式,下面舉例:
?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 var Person=function(name,age){ this.name=name; this.age=age; } Person.prototype={ constructor:Person, init:function(msg){ this.say(msg); }, say:function(msg){ alert(this.name+'說'+msg); } }; var tom=new Person('tom',23); tom.init('你好');// tom說你好其實jQuery也是采用的這種方式只不過用了更聰明的寫法,一起再看看jQuery的構造函數有什麼不同
?
1 2 3 4 5 // Define a local copy of jQuery var jQuery = function( selector, context ) { // The jQuery object is actually just the init constructor 'enhanced' return new jQuery.fn.init( selector, context, rootjQuery ); },從源碼中可以看到在jQuery真正的函數是init方法,當我們調用jQuery時會返回new init()的結果而不直接new jQuery() .
jQuery.fn是啥呢,在後面我們會看到這樣一句代碼
?
1 jQuery.fn = jQuery.prototype = {...這樣就很好理解了,其實jQuery.fn就是原型對象也就是說在jQuery原型裡面有一個init方法,這個方法是真正的構造函數。這樣寫的好處就是不需要在寫$().init()這樣的操作,直接就初始化了,但是還有一個問題就是既然init才是構造函數那我們寫在jQuery上面的那麼方法實例不是不能調用嗎?init的實例化自然只能調用init的方法啦,往後看到這樣一句代碼
?
1 2 // Give the init function the jQuery prototype for later instantiation jQuery.fn.init.prototype = jQuery.fn;之前講過jQuery.fn=jQuery.protype,這就意味著jQuery的原型對象賦給了init的原型,這樣jQuery的原型方法自然init也就都有了,通過這樣構造方式S使得使用jQuery方法非常簡單既不需要new jQuery()的操作也不需要手動初始化就行調用普通函數一樣簡單。