jquery的總體代碼架構簡化以下:jquery
(function( window, undefined ) { //...定義各類變量 jQuery = function( selector, context ) { return new jQuery.fn.init( selector, context, rootjQuery ); }, jQuery.fn = jQuery.prototype = { constructor: jQuery, init: function( selector, context, rootjQuery ) {}, ... }; jQuery.fn.init.prototype = jQuery.fn; if ( typeof window === "object" && typeof window.document === "object" ) { window.jQuery = window.$ = jQuery; } })( window );
這裏有幾點須要整明白的:
一、使用一個閉包定義jquery,建立一個私有空間,這樣內外部的命名空間就不會相互干擾了。爲了在外部可以使用jquery,將jquery($)提高到window做用域下,即:chrome
window.jQuery = window.$ = jQuery;
二、爲何要將window做爲參數傳入:
有兩個好處,一是便於代碼壓縮,jquery每一個版本都有壓縮版,如將傳入的window參數命名爲w,則可減小大量的代碼量;二是將window全局變量變成局部變量,可加快訪問速度。瀏覽器
三、爲何要增長undefined參數:
undefined在某些瀏覽器(如chrome、ie等)是能夠被修改的,如:閉包
undefined = "hello";
爲了保證在jQuery內部,使用到的undefined真的是undefined而沒有被修改過,將它做爲參數傳入。
ok,上面幾點都比較好理解,下面開始分析jquery的構建方式。
jQuery至關於一個類,在jquery中,咱們使用$()或jQuery()來獲得jquery實例,按此思路定義jQuery類以下:架構
var jQuery = function() { return new jQuery(); }
啊噢,死循環了~
想拿到實例,即this,原方法拿不到,就去原型那裏拿咯:this
var jQuery = function() { return jQuery.prototype.init(); } jQuery.prototype = { init:function() { return this; } }
但這樣仍是會有問題,由於這樣至關於單例了,建立出來的對象相互共享做用域,必然致使不少問題,如prototype
var jQuery = function() { return jQuery.prototype.init(); } jQuery.prototype = { init:function() { return this; }, age:18 } var jq1 = new jQuery(); var jq2 = new jQuery(); jq1.age = 20; console.log(jq1.age); //20 console.log(jq2.age); //20
因此須要讓他們的做用域分離,互不干擾,故每次建立新對象便可解決:code
var jQuery = function() { return new jQuery.prototype.init(); } jQuery.prototype = { init:function() { return this; } }
可是這樣仍然是有問題的,如:對象
var jQuery = function() { return new jQuery.prototype.init(); } jQuery.prototype = { init:function() { return this; }, age:18 } var jq = new jQuery(); console.log(jq.age); //undefined
緣由是這裏init和外部的jquery.prototype分離了,init對象中並無age屬性。
改改改:作用域
var jQuery = function() { return new jQuery.prototype.init(); } jQuery.prototype = { init:function() { return this; }, age:18 } jQuery.prototype.init.prototype = jQuery.prototype;
好了,到此爲止基本沒啥問題了,jQuery也是這樣實現的,只是多了個jQuery.fn做爲jQuery.prototype的引用而已,沒多少特別意義。