背景

因為最近辭職找工作,投了許多家公司。結(jié)果簡歷要么石沉大海,一點音訊都沒有,要么就是郵件回復說不匹配。后面加了一些QQ群,才發(fā)現(xiàn)原來我工作經(jīng)驗年限太少了?,F(xiàn)在深圳都是3經(jīng)驗起步,北京據(jù)說更加恐怖。

宅居在出租房中發(fā)愁的時候,看到群里大神說如果在簡歷上加上一句熟讀jquery源碼+vue源碼,那么3年經(jīng)驗就不再是一個問題,說到底還是能力不夠。

當時感覺心中為之一怔,于是開始一邊看源碼一邊做筆記,才有這個博客的開始。

老王:"上網(wǎng)搜搜jQuery源碼,一大把源碼資料講解。你這個博客不會直接是復制粘貼,源碼注釋流吧?那你的博客有啥看頭!"

車大棒;'咳咳??!老王你又過來砸場子這樣不好吧!當然今天你又砸到鋼板了,作為一名前端段子手我會給讀者復制粘貼看代碼注釋嗎?'

我可是一條有夢想的咸魚!

匿名函數(shù)

函數(shù)的創(chuàng)建

在了解什么是匿名函數(shù)之前,讓我們先來上一段創(chuàng)建函數(shù)最常見的的形式。

  var Hello = function(){    do something......
}

這種形式看起來好像是常規(guī)變量的賦值語句,即創(chuàng)建一個函數(shù)并將它賦值給變量Hello。這種情況下創(chuàng)建的函數(shù)叫做匿名函數(shù)(annoymous function),因為function關(guān)鍵字后面沒有標識符。

那么問題來了,如果不用一個變量去接受這個匿名函數(shù)。那么如何才能調(diào)用這個匿名函數(shù)呢?

匿名函數(shù)自調(diào)用

說到匿名函數(shù)自調(diào)用,有的小伙伴可能就會嘗試直接單獨把function拿出來,然后再調(diào)用。

 function(){console.log(1)}()        //驗證猜想

那么接下來讓我們輸出這行代碼,看瀏覽器是否正常的解析這行代碼。然后成功的在控制臺輸出數(shù)字1

結(jié)果瀏覽器很不給面子的解析失敗,還給你報出一串紅色警告字符。是不是感覺很委屈,恐怕瀏覽器才委屈吧。因為你沒有按照瀏覽器的規(guī)則來,瀏覽器當然會不給面子給你紅色警告。

道理其實很簡單,當js編譯器開始執(zhí)行的時候,碰見function之后??吹剿車鷽]有任何東西。于是就把function關(guān)鍵字解析成函數(shù)聲明,因此導致后面運行出錯了。
原文地址:https://stackoverflow.com/questions/13341698/javascript-plus-sign-in-front-of-function-name

這個時候我們只需要用一個括號把這個匿名函數(shù)包裹起來,避免js編譯器將function關(guān)鍵字解析成函數(shù)聲明,然后代碼就能夠正常執(zhí)行。

匿名函數(shù)調(diào)用非主流的寫法

當然除了主流常用的函數(shù)自調(diào)用寫法,還是有其他非主流的寫法。

同理因為function前面有這些運算符,因此js編譯器就把后面的匿名函數(shù)當作一個整體,沒有將關(guān)鍵字function去解析。

但是既然是非主流的寫法,就肯定會存在淪為非主流寫法所帶來的坑。還是前面的代碼,我分開輸出并在每行里面添加一個return 1.結(jié)果每一行出現(xiàn)的結(jié)果各不相同。

這是因為匿名函數(shù)也是一種值,這些運算符會將后面的函數(shù)體當成一個整體,先對匿名函數(shù)進行求值,然后在對結(jié)果進行運算。

所以在使用這些非主流的函數(shù)自調(diào)用寫法要注意這些坑,別因為追求個(裝)性(B)而導致后面出現(xiàn)問題就尷尬了。

jQuery:匿名自執(zhí)行函數(shù)

當我們打開jQuery源碼的時候,前面提到主流的匿名函數(shù)結(jié)構(gòu)一下子呈現(xiàn)眼前。

(function( window, undefined ) {    // jquery code})(window);

為什么要傳入window呢?

通過傳入window變量,使得window由全局變量變?yōu)榫植孔兞?,當在jQuery代碼塊中訪問window時,不需要將作用域鏈回退到頂層作用域,這樣可以更快的訪問window;這還不是關(guān)鍵所在,更重要的是,將window作為參數(shù)傳入,可以在壓縮代碼時進行優(yōu)化,看看jQuery壓縮代碼:

(function(a,b){})(window);               // window 被優(yōu)化為 a

可以被修改的undefined

眾所周知undefined屬于JavaScript基本數(shù)據(jù)類型中的一種類型,undefined
是全局對象的屬性即它是全局范圍的變量。初始值undefined是原始值。
但是在ES5規(guī)范之前,undefined是可以被定義。

undefined = "one Dog"alert(undefined)                      // 不遵守ES5規(guī)范的瀏覽器就會輸出one dog

本來我還在想去哪里找不遵守ES5版本的瀏覽器,結(jié)果就想起來IE。于是經(jīng)過測試IE6、IE7、IE8全部都能夠彈出"one Dog"

因為undefined能夠被重寫,賦予新的值。所以早期jQuery在自調(diào)用匿名函數(shù) 的作用域內(nèi),為了確保undefined是真的未定義。(早期可是IE天下)

為什么jQuery采用匿名函數(shù)

采用匿名函數(shù)自執(zhí)行,就可以形成一個巨大的作用域。里面擁有很多不用擔心被污染的局部變量,之后只需要開放暴露一個接口就可以了。

好吧,估計在這里有人就開始有一點頭暈了。沒有關(guān)系,讓我們回歸到舉栗子環(huán)節(jié)當中:

(function( window, undefined ) {   var $ =  "車大棒";
})(window);console.log($)

如上一個匿名函數(shù)形成了一個作用域,然后$符就是其中的局部變量。這個時候如果我們直接去拿這個$變量,console.log($)那么瀏覽器肯定會報如下錯。

那么這個時候,我就通過暴露接口,讓外面可以通過接口直接訪問到這個$這個變量。

(function( window, undefined ) {   var $ =  "車大棒";    window.$ = $;
})(window);console.log($)

那樣便能夠成功訪問到這個我定義的局部變量$

同理jQuery源碼里面也是如此,通過window去暴露一個接口。

是不是感覺,我嚓!這么簡單粗暴?。~,不簡單粗暴點估計你們都不愿意看了)

小結(jié):

本節(jié)主要是對于一個匿名函數(shù)的小結(jié),通過研究jQuery源碼從而間接的幫助大家溫習和回顧以前的JavaScript知識點。
原創(chuàng)文章,文筆有限,才疏學淺,文中若有不正之處,歡迎各位啪啪的打臉賜教。

http://www.cnblogs.com/chedabang/p/6610062.html