背景
因為最近辭職找工作,投了許多家公司。結果簡歷要么石沉大海,一點音訊都沒有,要么就是郵件回復說不匹配。后面加了一些QQ群,才發現原來我工作經驗年限太少了。現在深圳都是3經驗起步,北京據說更加恐怖。
宅居在出租房中發愁的時候,看到群里大神說如果在簡歷上加上一句熟讀jquery源碼+vue源碼,那么3年經驗就不再是一個問題,說到底還是能力不夠。
當時感覺心中為之一怔,於是開始一邊看源碼一邊做筆記,才有這個博客的開始。
老王:"上網搜搜jQuery源碼,一大把源碼資料講解。你這個博客不會直接是復制粘貼,源碼注釋流吧?那你的博客有啥看頭!"
車大棒;'咳咳!!老王你又過來砸場子這樣不好吧!當然今天你又砸到鋼板了,作為一名前端段子手我會給讀者復制粘貼看代碼注釋嗎?'
我可是一條有夢想的咸魚!
匿名函數
函數的創建
在了解什么是匿名函數之前,讓我們先來上一段創建函數最常見的的形式。
var Hello = function(){
do something......
}
這種形式看起來好像是常規變量的賦值語句,即創建一個函數並將它賦值給變量Hello。這種情況下創建的函數叫做匿名函數(annoymous function),因為function關鍵字后面沒有標識符。
那么問題來了,如果不用一個變量去接受這個匿名函數。那么如何才能調用這個匿名函數呢?
匿名函數自調用
說到匿名函數自調用,有的小伙伴可能就會嘗試直接單獨把function拿出來,然后再調用。
function(){console.log(1)}() //驗證猜想
那么接下來讓我們輸出這行代碼,看瀏覽器是否正常的解析這行代碼。然后成功的在控制台輸出數字1
結果瀏覽器很不給面子的解析失敗,還給你報出一串紅色警告字符。是不是感覺很委屈,恐怕瀏覽器才委屈吧。因為你沒有按照瀏覽器的規則來,瀏覽器當然會不給面子給你紅色警告。
道理其實很簡單,當js編譯器開始執行的時候,碰見function之后。看到它周圍沒有任何東西。於是就把function關鍵字解析成函數聲明,因此導致后面運行出錯了。
原文地址:https://stackoverflow.com/questions/13341698/javascript-plus-sign-in-front-of-function-name
這個時候我們只需要用一個括號把這個匿名函數包裹起來,避免js編譯器將function關鍵字解析成函數聲明,然后代碼就能夠正常執行。
匿名函數調用非主流的寫法
當然除了主流常用的函數自調用寫法,還是有其他非主流的寫法。
同理因為function前面有這些運算符,因此js編譯器就把后面的匿名函數當作一個整體,沒有將關鍵字function去解析。
但是既然是非主流的寫法,就肯定會存在淪為非主流寫法所帶來的坑。還是前面的代碼,我分開輸出並在每行里面添加一個return 1.結果每一行出現的結果各不相同。
這是因為匿名函數也是一種值,這些運算符會將后面的函數體當成一個整體,先對匿名函數進行求值,然后在對結果進行運算。
所以在使用這些非主流的函數自調用寫法要注意這些坑,別因為追求個(裝)性(B)而導致后面出現問題就尷尬了。
jQuery:匿名自執行函數
當我們打開jQuery源碼的時候,前面提到主流的匿名函數結構一下子呈現眼前。
(function( window, undefined ) {
// jquery code
})(window);
為什么要傳入window呢?
通過傳入window變量,使得window由全局變量變為局部變量,當在jQuery代碼塊中訪問window時,不需要將作用域鏈回退到頂層作用域,這樣可以更快的訪問window;這還不是關鍵所在,更重要的是,將window作為參數傳入,可以在壓縮代碼時進行優化,看看jQuery壓縮代碼:
(function(a,b){})(window); // window 被優化為 a
可以被修改的undefined
眾所周知undefined屬於JavaScript基本數據類型中的一種類型,undefined
是全局對象的屬性即它是全局范圍的變量。初始值undefined是原始值。
但是在ES5規范之前,undefined是可以被定義。
undefined = "one Dog"
alert(undefined) // 不遵守ES5規范的瀏覽器就會輸出one dog
本來我還在想去哪里找不遵守ES5版本的瀏覽器,結果就想起來IE。於是經過測試IE6、IE7、IE8全部都能夠彈出"one Dog"
因為undefined能夠被重寫,賦予新的值。所以早期jQuery在自調用匿名函數 的作用域內,為了確保undefined是真的未定義。(早期可是IE天下)
為什么jQuery采用匿名函數
采用匿名函數自執行,就可以形成一個巨大的作用域。里面擁有很多不用擔心被污染的局部變量,之后只需要開放暴露一個接口就可以了。
好吧,估計在這里有人就開始有一點頭暈了。沒有關系,讓我們回歸到舉栗子環節當中:
(function( window, undefined ) {
var $ = "車大棒";
})(window);
console.log($)
如上一個匿名函數形成了一個作用域,然后$符就是其中的局部變量。這個時候如果我們直接去拿這個$變量,console.log($)
那么瀏覽器肯定會報如下錯。
那么這個時候,我就通過暴露接口,讓外面可以通過接口直接訪問到這個$這個變量。
(function( window, undefined ) {
var $ = "車大棒";
window.$ = $;
})(window);
console.log($)
那樣便能夠成功訪問到這個我定義的局部變量$
同理jQuery源碼里面也是如此,通過window去暴露一個接口。
是不是感覺,我嚓!這么簡單粗暴!(額,不簡單粗暴點估計你們都不願意看了)
小結:
本節主要是對於一個匿名函數的小結,通過研究jQuery源碼從而間接的幫助大家溫習和回顧以前的JavaScript知識點。
原創文章,文筆有限,才疏學淺,文中若有不正之處,歡迎各位啪啪的打臉賜教。
我是車大棒,我的目標是星辰與大海!