- 相關(guān)推薦
javascript閉包的介紹理解和講解實(shí)例
順便提示一下:
詞法作用域:變量的作用域是在定義時(shí)決定而不是執行時(shí)決定,也就是說(shuō)詞法作用域取決于源碼,通過(guò)靜態(tài)分析就能確定,因此詞法作用域也叫做靜態(tài)作用域。 with和eval除外,所以只能說(shuō)JS的作用域機制非常接近詞法作用域(Lexical scope)。
下面是一個(gè)簡(jiǎn)單的使用全局變量的閉包實(shí)例:
復制代碼 代碼如下:
var sWord="Hello,Welcome to web前端開(kāi)發(fā)工程師的博客,請多多指教。"
function disWord(){
alert(sWord);
}
disWord();
解析:腳本載入到內存的時(shí)候,disWord并沒(méi)有計算sWord的值,而是函數disWord調用的時(shí)候執行了sWord的計算。
下面是函數中定義另一個(gè)函數的閉包實(shí)例:
復制代碼 代碼如下:
var iNum=10;
function add(num1,num2){
function doAdd(){return num1+num2+iNum;}
return doAdd();
}
解析:內部函數doAdd是個(gè)閉包,它將獲取傳入參數num1,num2和全局變量iNum的值,doAdd不接受參數,add最后一步調用doAdd,請兩個(gè)參數和全局變量求和返回,可以看得出doAdd使用的值是在執行環(huán)境中獲得的。
下面是在網(wǎng)上找的幾個(gè)例子,理解詞法作用域和閉包
復制代碼 代碼如下:
、案例一
/*全局(window)域下的一段代碼*/
function a(i) {
var i;
alert(i);
};
a(10);
疑問(wèn):上面的代碼會(huì )輸出什么呢?
答案:10。
具體執行過(guò)程
a 函數有一個(gè)形參 i,調用 a 函數時(shí)傳入實(shí)參 10,形參 i=10
接著(zhù)定義一個(gè)同名的局部變量 i,未賦值
alert 輸出 10
思考:局部變量 i 和形參 i 是同一個(gè)存儲空間嗎?
、案例二
復制代碼 代碼如下:
1 /*全局(window)域下的一段代碼*/
2 function a(i) {
3 alert(i);
4 alert(arguments[0]); //arguments[0]應該就是形參 i
5 var i = 2;
6 alert(i);
7 alert(arguments[0]);
8 };
9 a(10);
疑問(wèn):上面的代碼又會(huì )輸出什么呢?
答案:10,10,2,2
具體執行過(guò)程
函數有一個(gè)形參i,調用 a 函數時(shí)傳入實(shí)參 10,形參 i=10
第一個(gè) alert 把形參 i 的值 10 輸出
第二個(gè) alert 把 arguments[0] 輸出,應該也是 i
接著(zhù)定義個(gè)局部變量 i 并賦值為2,這時(shí)候局部變量 i=2
第三個(gè) alert 就把局部變量 i 的值 2 輸出
第四個(gè)alert再次把 argumentsa[0] 輸出
思考:這里能說(shuō)明局部變量 i 和形參 i 的值相同嗎?
、案例三
復制代碼 代碼如下:
/*全局(window)域下的一段代碼*/
function a(i) {
var i = i;
alert(i);
};
a(10)
疑問(wèn):上面的代碼又又會(huì )輸出什么呢?
答案:10
具體執行過(guò)程
第一句聲明一個(gè)與形參 i 同名的局部變量 i,根據結果我們知道,后一個(gè) i 是指向了
形參 i,所以這里就等于把形參 i 的值 10 賦了局部變量 i
第二個(gè) alert 當然就輸出 10
思考:結合案列二,這里基本能說(shuō)明局部變量 i 和形參 i 指向了同一個(gè)存儲地址!
、案例四
復制代碼 代碼如下:
/*全局(window)域下的一段代碼*/
var i=10;
function a() {
alert(i);
var i = 2;
alert(i);
};
a();
疑問(wèn):上面的代碼又會(huì )輸出什么呢?
答案:undefined, 2
具體執行過(guò)程
第一個(gè)alert輸出undefined
第二個(gè)alert輸出 2
思考:到底怎么回事兒?
看到上面的幾個(gè)例子,你可能會(huì )想到底是怎么執行的呢?執行的細節又是怎么樣的呢? JS 引擎的工作方式是怎樣的呢?
解析過(guò)程
、執行順序
編譯型語(yǔ)言,編譯步驟分為:詞法分析、語(yǔ)法分析、語(yǔ)義檢查、代碼優(yōu)化和字節生成。
解釋型語(yǔ)言,通過(guò)詞法分析和語(yǔ)法分析得到語(yǔ)法分析樹(shù)后,就可以開(kāi)始解釋執行了。這里是一個(gè)簡(jiǎn)單原始的關(guān)于解析過(guò)程的原理,僅作為參考,詳細的解析過(guò)程(各種JS引擎還有不同)還需要更深一步的研究
javascript的執行過(guò)程,如果一個(gè)文檔流中包含多個(gè)script代碼段(用script標簽分隔的js代碼或引入的js文件),它們的運行順序是:
步驟1. 讀入第一個(gè)代碼段(js執行引擎并非一行一行地執行程序,而是一段一段地分析執行的)
步驟2. 做詞法分析和語(yǔ)法分析,有錯則報語(yǔ)法錯誤(比如括號不匹配等),并跳轉到步驟5
步驟3. 對【var】變量和【function】定義做“預解析“(永遠不會(huì )報錯的,因為只解析正確的聲明)
步驟4. 執行代碼段,有錯則報錯(比如變量未定義)
步驟5. 如果還有下一個(gè)代碼段,則讀入下一個(gè)代碼段,重復步驟2
步驟6. 結束
、特殊說(shuō)明
全局域(window)域下所有JS代碼可以被看成是一個(gè)“匿名方法“,它會(huì )被自動(dòng)執行,而此“匿名方法“內的其它方法則是在被顯示調用的時(shí)候才被執行
、關(guān)鍵步驟
上面的過(guò)程,我們主要是分成兩個(gè)階段
解析:就是通過(guò)語(yǔ)法分析和預解析構造合法的語(yǔ)法分析樹(shù)。
執行:執行具體的某個(gè)function,JS引擎在執行每個(gè)函數實(shí)例時(shí),都會(huì )創(chuàng )建一個(gè)執行環(huán)境(ExecutionContext)和活動(dòng)對象(activeObject)(它們屬于宿主對象,與函數實(shí)例的生命周期保持一致)
在這里有更詳細的實(shí)例分析資料:/article/24547.htm
【javascript閉包的介紹理解和講解實(shí)例】相關(guān)文章:
javascript閉包的定義及應用實(shí)例分析08-25
javascript的閉包概念怎么理解06-15
JavaScript的課堂講解09-03
對javascript的理解08-08
JavaScript fontcolor方法入門(mén)實(shí)例07-07
JavaScript中push(),join() 函數實(shí)例詳解09-05
理解JavaScript原型鏈教程09-02
有關(guān)深入理解JavaScript中的并行處理的介紹10-14
實(shí)例講解托福閱讀推斷題技巧06-20