Jquery源碼中的Javascript基礎知識(三)
這篇主要說一下在源碼中jquery對象是怎樣設計實現的,下面是相關代碼的簡化版本: 複製代碼 1 (function( window, undefined ) { 2 // code 定義變數 3 jQuery = function( selector, context ) { 4 return new jQuery.fn.init( selector, context, rootjQuery ); 5 }, 6 // code 定義變數 7 jQuery.fn = jQuery.prototype = { 8 jquery: core_version, 9 constructor: jQuery,10 init: function( selector, context, rootjQuery ) {11 // code 初始化、參數處理12 }13 // code 一些方法(each、ready、first、eq等)14 }15 jQuery.fn.init.prototype = jQuery.fn;16 // code 其他17 if ( typeof window === "object" && typeof window.document === "object" ) {18 window.jQuery = window.$ = jQuery;19 }20 })( window );複製代碼首先,回顧一下javascript中相關知識。 在javascript中特定類型的對象是通過建構函式來建立的,例如: 複製代碼 1 function Person(name){ 2 this.name = name; 3 this.sayName = function(){ 4 alert(this.name); 5 } 6 } 7 // 作為普通函數使用 8 Person('Yanger90'); 9 window.sayName();10 11 // 作為建構函式使用12 var person = new Person('Yanger90');13 person.sayName();複製代碼更好的方式-原型模式 複製代碼function Person(){}Person.prototype = { name: "Yanger90", syaName: function(){ console.log(this.name); }};var person = new Person();複製代碼每一個函數都有一個prototype(原型)屬性,裡麵包含的屬性和方法,是所有通過該建構函式建立的執行個體對象所共用的。對於一些公用的方法,像例子中的sayName方法,就可以放在原型中共用而不用像第一種方式那樣,每個執行個體對象都要重新建立一遍。 好了,基礎知識就簡單介紹到這,詳細可參閱《javascript進階程式設計》這本書。 回到jquery中,我們一般使用jquery文法類似這樣: $(element).css();選擇元素然後執行相應方法,那麼前面的$(element)就應該是一個執行個體對象,再調用其方法。 我們看到在源碼開始的部分就定義了jQuery變數: jQuery = function( selector, context ) { return new jQuery.fn.init( selector, context, rootjQuery );}它確實返回了一個執行個體對象,建構函式是init,接著往下看。 複製代碼jQuery.fn = jQuery.prototype = { jquery: core_version, constructor: jQuery, // 修正以字面量方式重寫原型對象造成的指向問題 init: function( selector, context, rootjQuery ) { // code 初始化、參數處理 } // code 一些方法(each、ready、first、eq等)}複製代碼找到init發現它是jQuery原型(prototype)中的一個方法。 問題來了,init方法中只是對參數進行了處理,並沒有我們常用的each、ready、first、eq等方法,它們都在jQuery原型(prototype)中,所以還無法調用這些方法,那麼繼續往後看。 jQuery.fn.init.prototype = jQuery.fn;這句話把init的原型指向了jQuery.fn,也就是jQuery.prototype,這樣一來,jQuery原型(prototype)中的屬性和方法就共用給了通過init建構函式建立的執行個體對象,也就實現了繼承。 最後,在jquery源碼的末尾有一句 window.jQuery = window.$ = jQuery;jQuery是在匿名函數中定義的,所以外部是無法訪問的,這裡將它賦值給window對象的屬性,這樣我們就可以在外部直接使用了。