在普通情況下我們要用原生類、或者自定義類創(chuàng)建實例要用new運算符,使構(gòu)造函數(shù)創(chuàng)建一個實例,并且實例繼承構(gòu)造器prototype上的所有公有方法。如 new Object()、new Date()等等!(object有{},數(shù)組有[]這樣的快捷方式 ,我們主要探討new這種方式。)
我們在使用jQuery時從來沒有使用過new,他是不是用其他方法來生成實例呢?是不是沒有使用prototype屬性呢?事實上他都有使用,只是內(nèi)部處理的非常巧妙,提高了使用的爽快度。我們來看看他的源碼
funtion jQuery( selector, context){ return new jQuery.fn.init( selector, context ); }
這里可以看出jQuery是有構(gòu)造函數(shù)的,也是用了new 創(chuàng)建實例的。那么jQuery.fn是什么呢?后面有個這樣的處理:
jQuery.fn = jQuery.prototype={ init:function (){} }
這樣我們就明白了,jQuery的構(gòu)造函數(shù)是他原型上的init方法,而不是function jQuery。這樣的話每次調(diào)用$()他都會用jQuery原型上的init創(chuàng)建一個實例,那么新的問題來了。如果用init創(chuàng)建實例的話,這個對象繼承的是init的prototype上的方法而不會繼承jQuery prototype上的方法,那么他是怎么實現(xiàn)原型繼承的呢?
jQuery.fn.init.prototype = jQuery.fn;
這里他有一個這樣的處理,把jQuery.fn賦值給了jQuery.fn.init.prototype ,這一步很關(guān)鍵。我門看看這些是什么。
jQuery.fn是jQuery.prototype
jQuery.fn.init.prototype是jQuery.prototype.init.prototype
這個處理相當于
jQuery.prototype = jQuery.prototype.init.prototype
那么每當我們調(diào)用$()是,jQuery就會用new運算符調(diào)用他prototype上的init創(chuàng)建一個實例,這個由init創(chuàng)建實例會繼承jQuery protype上的所有方法,并且這個實例的__proto__內(nèi)部屬性會指向jQuery的prototype屬性。
另外我們注意到這個處理:
jQuery.fn = jQuery.prototype
這是他為了避免頻繁的操作jQuery.prototype,所以用jQuery.fn緩存了jQuery.prototype。
這些的處理實在是非常巧妙,內(nèi)部處理了實例創(chuàng)建不用使用者用new去生成實例,又非常漂亮的處理了prototype保證多實例共享方法減少資源開支,約翰哥真的不簡單。