1哭廉、jQuery設(shè)計理念
正如jQuery的標(biāo)題:The Write Less,Do More鬓椭,無疑這就是jQuery的核心理念,這里面讓人激動的設(shè)計有簡潔的API、優(yōu)雅的鏈?zhǔn)健?qiáng)大的查詢與便捷的操作扁眯。
簡潔的API
$.on
$.css
$.ajax
….
優(yōu)雅的鏈?zhǔn)?/strong>
var xhr = $.ajax( "./example.php" )
.done(function() { alert("success"); })
.fail(function() { alert("error"); })
類CSS的選擇器
$("div, span, p.myClass" )
$("div span:first-child")
...
便捷的操作
$("p").removeClass("myClass noClass").addClass("yourClass");
$("ul li:last").addClass(function(index) {
return "item-" + index;
});
$('.container').append($('h2'));
…
2疫衩、立即調(diào)用表達(dá)式
任何庫或者框架設(shè)計的第一個需要考慮的點就是解決命名空間和全局變量污染的問題硅蹦,jQuery利用了JavaScript函數(shù)作用域的特性,采用立即執(zhí)行函數(shù)包裹了自身的方法來解決這個問題闷煤。建議在下面的閱讀前童芹,如果對立即執(zhí)行函數(shù)不是很理解的小伙伴們,先閱讀下我寫的另一篇文章:JavasSript-立即執(zhí)行函數(shù)
jQuery的立即調(diào)用函數(shù)表達(dá)式的寫法吧
one
(function(window, factory) {
factory(window)
}(this, function() {
return function() {
//jQuery的調(diào)用
}
}))
相必很多同學(xué)看到這里鲤拿,和我當(dāng)時一樣都很懵逼吧假褪,其實不用著急,對于復(fù)雜的代碼我們學(xué)會將其拆分為我們熟悉的知識結(jié)構(gòu)皆愉,然后簡化它就好了嗜价。這里我們可以開始剖解它
//相信這樣大家很容易理解,對啊就是一個簡單的匿名函數(shù)執(zhí)行函數(shù)的兩種寫法
(function() {
/*code*/
})()
or
(function() {
/*code*/
}())
下面我們再看一個傳參的立即執(zhí)行函數(shù)
(function(a,b) {
/*code*/
}(c,d))
我們知道在javascript中函數(shù)作為一等公民幕庐,我們可以將一個函數(shù)作為參數(shù)傳入另一個函數(shù)中
//這里的factory是一個形參函數(shù)
(function(window, factory) {
factory(window)
}(this, function() {
return function() {
//jQuery的調(diào)用
}
}))
//整個這樣一段就是給上面的匿名函數(shù)傳入第一個實參this久锥,第二個實參一個function,并立即執(zhí)行
(this, function() {
return function() {
//jQuery的調(diào)用
}
})
相比上面的經(jīng)過簡化分析后异剥,大家都應(yīng)該看的懂瑟由,那么想必大家肯定有一個疑問為什么要搞得怎么復(fù)雜,其實我前面已經(jīng)說過了任何庫或者框架設(shè)計的第一個需要考慮的點就是解決命名空間和全局變量污染的問題冤寿,下面我們接著看第二種簡單點的寫法
two
var factory = function(){
return function(){
//執(zhí)行方法
}
}
var jQuery = factory();
其實上面的代碼效果和第一種寫法是等同的歹苦,納尼?想必寫道這里很多人會說那你前面搞的那么復(fù)雜干嘛督怜,故作高深的裝逼殴瘦,哈哈,請接著看号杠。
上面的factory函數(shù)有點變成了簡單的工廠方法模式蚪腋,需要自己調(diào)用,當(dāng)時我們需要的是一個“自執(zhí)行”的啊姨蟋,并不是另外調(diào)用的屉凯,而且上面的寫法雖然簡單,卻很容易造成全局變量的污染眼溶,這是一種魔鬼悠砚。這里順便安利一下《JavaScript語言精粹》這本書哈,這本書將告訴那些是JS中優(yōu)雅的特性和盡量避免使用的特性堂飞。
下面我們再看一下最后一種寫法吧
three
(function(window, undefined) {
var jQuery = function() {}
// ...
window.jQuery = window.$ = jQuery;
})(window);
從上面的代碼可看出灌旧,自動初始化這個函數(shù)绑咱,讓其只構(gòu)建一次。詳細(xì)說一下這種寫法的優(yōu)勢:
- window和undefined都是為了減少變量查找所經(jīng)過的scope作用域枢泰。當(dāng)window通過傳遞給閉包內(nèi)部之后羡玛,在閉包內(nèi)部使用它的時候,可以把它當(dāng)成一個局部變量宗苍,顯然比原先在window scope下查找的時候要快一些
- undefined也是同樣的道理稼稿,其實這個undefined并不是JavaScript數(shù)據(jù)類型的undefined,而是一個普普通通的變量名讳窟。只是因為沒給它傳遞值让歼,它的值就是undefined,undefined并不是JavaScript的保留字丽啡。
可能會有疑問谋右,為什么要傳遞一個undefined啊补箍?這里我們可以這樣理解:Javascript 中的 undefined 并不是作為關(guān)鍵字改执,因此可以允許用戶對其賦值 ,簡單點就是如果函數(shù)調(diào)用不傳遞坑雅,參數(shù)默認(rèn)就是undefined
最后總結(jié)一下jQuery為什么要創(chuàng)建這樣的一個外層包裹辈挂,其原理又是如何?
- 首先我們分析下寫法2裹粤,其實這就可以理解為一個簡單的工廠函數(shù)啊终蒂,我們可以在下面執(zhí)行n次調(diào)用。
- 那么寫法3遥诉,首先我們這里需要區(qū)分2個概念一個是匿名函數(shù)拇泣,一個是自執(zhí)行。顧名思義矮锈,匿名函數(shù)霉翔,就是沒有函數(shù)名的函數(shù),也就是不存在外部引用了苞笨。這樣匿名函數(shù)可以有效的保證在頁面上寫入JavaScript债朵,而不會造成全局變量的污染,之后通過小括號猫缭,讓其加載的時候立即初始化葱弟,這樣就形成了一個單例模式的效果從而只會執(zhí)行一次壹店。
其實這里就是已經(jīng)再進(jìn)一步就涉及了設(shè)計模式中的工廠模式和單例模式猜丹,需要了解的可以參考下我的github:https://github.com/joinmouse/Design-Mode-