有段時間沒有更新了,思緒一下子有點轉不過來。正應了一句古話“一天不讀書,無人看得出;一周不讀書,開始會爆粗;一月不讀書,智商輸給豬。”。再加上周五晚上看了下很久沒看的湖南綜藝節目《天天向上》關於出版書及讀書的相關內容,看到相當多的嘉賓家里的書房讓我驚嘆也伴隨着一種文人的向往。我雖然小的時候不太愛看書,但是隨着自己一點點的長大,也不知道什么時候開始也有買書藏書看書的情節,而且正如郁鈞劍老師所說的藏書有點會上癮,即使有些書不是馬上就會看。挺希望以后不工作了,有自己的一間書屋,一方書桌,一把椅子,一壺茶水,悠然自得的讀書練習書法。
話題有點跑題了,切換模式回到這篇博客上來。在一次小組同事間分享的時候,有位同事給出了這樣一個代碼:
if (true) { function fn() { alert('為 true 時執行我!'); } } else { function fn() { alert('為 false 時執行我!'); } } fn()
大家可以看下,這段代碼執行的結果到底是什么?開啟你智慧的大腦吧!
好吧,下面是各主流瀏覽器的執行結果:
- 最愛的chrome:// 為 false 時執行我!
- 不用很久的firefox // 為 true 時執行我!
- IE7/8/9 // 為 false 時執行我!
哦,這是why?其實當我那同事問我們的時候,我的第一直覺就是 “為 true 時執行我!”。 后來,我想了想這個情況是不是瀏覽器在解析javascript的語法分析的時候有區別。
下面是我當時的猜想,大家不要當作是解釋以上代碼的理由:
1.chrome和IE在解析上述代碼的時候語法作用域解析的變量與函數聲明提升。大概是這樣的意思:
function fn() { alert('為 true 時執行我!'); } function fn() { alert('為 false 時執行我!'); } if (true) { function fn() { alert('為 true 時執行我!'); } } else { function fn() { alert('為 false 時執行我!'); } } fn()
所以后面的函數覆蓋前面的函數,所以才會是這樣的結果。
firefox的解析可能不太一樣,在處理語法作用域的時候,當函數聲明的時候在if語句中是按順序執行。
哈哈,以上也是自己的猜想,沒有去研究瀏覽器之間的源碼,能力有限,今日記下,日后有能 力再補上。也歡迎各路高手留言指點迷津。
分割,在我那個同事分享后放假就是五一,三天假期像我這樣的宅男只能看着別人帶着女朋友到處旅游;自個默默的只好宅在家里,三天休息也不是一點沒有收獲。三天有兩天下午到公園跑步跑6圈,不經常跑步,一跑起來真是上氣不接下氣,但還是堅持跑完了自己定下的6圈,畢竟做程序的沒有個好身體怎么行是吧?每晚,看會周愛民寫的《javascript語言精髓與編程實踐》,剛好看到模塊化的層次---語法作用域這一節,就有涉及上述代碼的解釋。
javascript語法作用域圖表:
特殊作用運算符圖
在這一節的語法作用域之間的相關性是這樣描述的:
結構化語言中,代碼塊的作用域是相互不相交的。這些作用域之間只存在平行或嵌套兩種相關性。
例如:
代碼平行:
/** * 示例1:代碼一與代碼二平行 */ // 代碼一 if (true){ // ... } // 代碼二 while (true) { // ... }
代碼嵌套:
/** * 示例2: 代碼一與代碼二嵌套 */ // 代碼一 if (true){ // ... // 代碼二 while (true) { // ... } }
結構化語言是通過代碼塊這種“互不相交”的特性來保證邏輯上的獨立,消除代碼塊之間的耦合。但是“嵌套”這種相關性中,代碼二與代碼一的語法作用域存在重疊。這種關系,就是通過前面所說的“語法作用域的級別”來控制。
- 相同級別的語法作用域可以相互嵌套
- 高級別的語法作用域能夠包含低級別的語法作用域
- 低級別的語法作用域不包含高級別的語法作用域。由於不存在包含關系,因此語言實現時,一般處理成語法的違例,或者理解為“平行”的關系。
規則一的示例:
/** * 規則1: 相同級別的代碼的嵌套 */ function fn1() { function fn2() { function fn3() { // .... } } }
規則二的示例:
/** * 規則2: 高級別代碼的嵌套低級別代碼 */ function fn1() { if (true) { // ... } }
規則三的示例:
/** * 規則3: 低級別代碼的嵌套高級別代碼 */ if (true) { function fn1() { // ... } } else { function fn1() { // ... } } // 低級別代碼不能包含高級別代碼,所以把這種嵌套關系理解成平行關系 if (true) { // .. } else { // ... } function fn1() { // ... } function fn1() { // ... } // 同名函數,后者覆蓋前者
至此,大家看到規則三的時候是不是很眼熟啊,的確,看到這示例就很快能理解之前我同事分享那段代碼在chrome和IE的執行結果是怎么一回事。
不過遺憾的是,沒能解釋為什么在firefox的執行原理,正如我前面個人的猜想的那樣吧,只不過目前自己還沒弄清在firefox的執行原理,不過那是遲早的事兒。還是那句話,歡迎大家不要吝惜自己的留言,把自己理解的分享給大家也是在提升自己。^_^!!!