1. 程式人生 > >jQuery原始碼分析一

jQuery原始碼分析一

最近在研究jQuery原始碼,jQuery原始碼近9000行,因此不可能一篇文章全都分析了,我會一點一點分析,每隔一段時間更新一點,儘量分析的詳細一點。
這篇文章我分享的是JQ採用的匿名函式自以及建構函式。

匿名函式自執行
(function(window,undefined){})(window);
jQuery採用的就是這段程式碼,從第14行到8829行,包裹住全文(我分析的版本是2.0.3的版本,你們可以自己從網上下載這個版本);

1.匿名函式自執行的一個優勢,內部的程式碼,不會外部衝突,內部汙染外部。
2.jQuery傳這兩個引數原因有兩個,第一個,window屬於js的最頂端,速度比較慢,根據作用域的原理,變數是從離他最近定義的地方開始查詢,所以說傳參之後,查詢速度就更加的快捷。第二個,window傳過來之後,對於壓縮版本也很有好處,我們要知道壓縮程式碼不僅僅只是壓縮換行和空格,函式內部的變數名它也會進行壓縮,例如window在jquery-2.0.3.min.js裡面被壓縮成了e,但是不傳參window則是函式外部的,無法被壓縮。
3.為什麼要傳undefined?因為undefined在某些情況下是可以被修改的,例如IE8 以下,定義var undefined=99;alert(undefined)為99,更多情況下它是不可被更改。所以為了防止外部有人修改undefined,jq將它傳了進來。
4.”use strict”嚴格開發模式,加了這句話表明開發模式為嚴格開發模式,我們必須嚴格遵守其規範,例如在非嚴格模式下允許寫八進位制形式,在嚴格模式下就不允許,但是jquery不支援這種寫法因為這種寫法在低版本瀏覽器下不相容只支援高版本的瀏覽器;再比如,我們定義一個a=10,並沒有用var定義,在非嚴格模式下不報錯,但是加上了“use strict”程式會報錯a is not defined,我們公司的移動框架還是支援的,畢竟移動端不需要考慮多少相容性成本。

建構函式
jQuery中的建構函式可以說其精華之一,我不得不讚嘆一下其作者。
1.普通的建構函式

function Aaa(){
    //這裡面定義一些屬性
}
//原型鏈中新增方法
Aaa.prototype.init = function(){};
Aaa.prototype.css = function(){};
//使用
var a1 = new Aaa();
a1.init();
a1.css();

2.jQuery中的建構函式

//window.jQuery = window.$ = jQuery;8826行
function jQuery(){
    return new jQuery.prototype.init();//亮點一,第63行
} jQuery.prototype.init = function(){} jQuery.prototype.css = function(){} jQuery.prototype.init.prototype = jQuery.prototype;//一個物件賦值給了另外一個物件,就出現了引用,亮點二,第283行 jQuery().css();//呼叫方法

可能有的人會覺得,不對啊,jQuey裡面不是這樣寫的,
63行寫的return new jQuery.fn.init( selector, context, rootjQuery );
283行寫的是jQuery.fn.init.prototype = jQuery.fn;
但是注意到第96行jQuery.fn = jQuery.prototype,我就喜歡叫fn你有什麼辦法嗎,上面的方法是我簡化之後樣子,jQuery簡化下來就是這個樣子,這裡我推薦張鑫旭老師的一篇文章,分析jQuery原理的,

http://www.zhangxinxu.com/wordpress/2013/07/jquery-%E5%8E%9F%E7%90%86-%E6%9C%BA%E5%88%B6/,寫的很好,也很幽默,不會很枯燥。

jQuery返回的是一個new操作符處理的例項化物件,在init方法裡面經過了一系列判斷處理,返回的其實就是類似document.getElementById()醬紫的東西。我們要知道,在new操作符實現建構函式例項化物件的時候,我們return 都是不用寫的,因為預設返回的是this,但若是改變了,返回的就是改變的東西,jQuery中返回自執行建構函式(init函式),在init裡面進行自己想要的操作,再用jQuery.prototype.init.prototype = jQuery.prototype賦值引用(引用大家應該都懂吧,傳值和傳址不懂的可以去百度百度),兩個指向同一個地址,也就是說,jQuery.prototype.init的原型即是我jQuery的原型,那樣我寫在jQuery的原型裡面或者是寫在jQuery.prototype.init的原型裡面不都可以嗎!