從一本有趣的js書說起
最近在逛某當搜索javascript的時候發(fā)現(xiàn)一本相當有趣的介紹js各種設(shè)計模式的教學(xué)書籍javascript設(shè)計模式(張容銘 著)這里給大家安利一下
當時看到推薦語里面的介紹說這本書是通過講述一個菜鳥程序員是如何在職場實踐中成長的就立馬勾起了我的興趣,特別是之后看到目錄里那一個個基本沒見過感覺上又很高大上的模式的詞匯更讓我下定決心要買這本書峭拘。
經(jīng)過數(shù)天的苦等蕴轨,這本勾起我強烈學(xué)習欲望的課本昨天終于到手了,恰逢今天是一星期一度的周末,剛好有很多時間可以休息和學(xué)習驹碍,于是今天就翻看了一下這本書背犯。首先第一章介紹了本書的主人公入職第一天參與項目任務(wù)時創(chuàng)建一大堆全局變量然后被教育了一整天的故事,接著第二章小白一大早就又被項目經(jīng)理教訓(xùn)了一番绍妨,然后委屈的小白去向第二主人公小銘求教润脸,小銘給小白講了一大堆面向?qū)ο缶幊痰乃枷牒头椒ǎ强吹?strong>靜態(tài)私有變量這個概念時我就懵了他去,我本科專業(yè)不是編程方向毙驯,雖然因為課程需要學(xué)過一點C語言和匯編,但對這個詞匯并沒有印象和概念(C語言沒學(xué)好)灾测,然后就引發(fā)了我今天一連串蝴蝶效應(yīng)的搜索
- 靜態(tài)變量
- 靜態(tài)私有變量
- 立即執(zhí)行函數(shù)
- Javascript函數(shù)聲明提升
在查找學(xué)習立即執(zhí)行函數(shù)相關(guān)知識通過一條外鏈讓我看到了一篇有關(guān)變量聲明提升和變量作用域Scoping & Hosting的博文爆价,博文中舉的第一個例子的“怪異”表現(xiàn)引起了我的注意
var a = 1;
function foo() {
if (!a) {
var a = 2; }
alert(a);};
foo();//2}
先說一下函數(shù)聲明提升吧
第一次接觸函數(shù)聲明提升是在
Javascript高級程序設(shè)計(第三版) 5.5.2 實際上,解析器在向執(zhí)行環(huán)境中加載數(shù)據(jù)時媳搪,對函數(shù)聲明和函數(shù)表達式并非一視同仁铭段。解析器會率先讀取函數(shù)聲明,并使其在執(zhí)行任何代碼之前可用(可以訪問)秦爆;第七章 函數(shù)表達式 關(guān)于函數(shù)聲明序愚,他的一個重要特征就是函數(shù)聲明提升(function declaration hoisting),意思是在執(zhí)行代碼之前會先讀取函數(shù)聲明。
中接觸到的等限,但是當時只是知道函數(shù)聲明有函數(shù)聲明提升(函數(shù)在加載時會率先讀取函數(shù)聲明)這個特性爸吮,并不知道變量聲明提升這個概念,也并不清楚javascript解析器的這個機制精刷。
回到alert(a);//2
本來很想分享一下我對js解析器對函數(shù)和變量聲明提升這一機制的一些理解拗胜,但是發(fā)現(xiàn)自己編輯了差不多兩個小時也還沒進入主題,今天就先不分享了怒允,這里就簡答的指出一下原博的一個錯誤
文中說
而無論 if語句的條件如何埂软,都將為新的變量 a 賦值為 2
而實際上并不是這樣,應(yīng)該是在函數(shù)內(nèi)部聲明了變量a,而JavaScript引擎在執(zhí)行的時候勘畔,會把所有變量的聲明都提升到當前作用域的最前面所灸,即相當于在當前函數(shù)作用域的最前端聲明了一個變量a而沒有給a賦值,此時a的數(shù)據(jù)類型應(yīng)該為undefined,所以在做if判斷時a轉(zhuǎn)換成的布爾值應(yīng)該為false,因此!a為true炫七,if語句才得以執(zhí)行爬立,如果將if(!a)改成if(a)則alert(a)將會為undefined。
var a = 1;
function foo(){
if(a){
var a = 2;
}
alert(a);
}
foo();//undefined
因為真的編輯了很長時間万哪,寫得我都有點頭昏腦漲了侠驯,邏輯有點混亂了,而且實際上并沒有多少內(nèi)容奕巍,希望大家仔細研究一下原文Scoping & Hosting吟策,歡迎大家一起指正討論學(xué)習進步,謝謝大家