javascript閉包的理解和例項
所謂閉包,值得是詞法表示包括不必要計算的變數的函式,也就是說,該函式可以使用函式外定義的變數。
順便提示一下:
詞法作用域:變數的作用域是在定義時決定而不是執行時決定,也就是說詞法作用域取決於原始碼,通過靜態分析就能確定,因此詞法作用域也叫做靜態作用域。 with和eval除外,所以只能說JS的作用域機制非常接近詞法作用域(Lexical scope)。
下面是一個簡單的使用全域性變數的閉包例項:
2 function disWord(){
3 alert(sWord);
4 }
5 disWord();
解析:指令碼載入到記憶體的時候,disWord並沒有計算sWord的值,而是函式disWord呼叫的時候執行了sWord的計算。
下面是函式中定義另一個函式的閉包例項:
2 function add(num1,num2){
3 function doAdd(){return num1+num2+iNum;}
4 return doAdd();
5 }
解析:內部函式doAdd是個閉包,它將獲取傳入引數num1,num2和全域性變數iNum的值,doAdd不接受引數,add最後一步呼叫doAdd,請兩個引數和全域性變數求和返回,可以看得出doAdd使用的值是在執行環境中獲得的。
下面是在網上找的幾個例子,理解詞法作用域和閉包
1、案例一
2 function a(i) {
3 var i;
4 alert(i);
5 };
6 a(10);
疑問:上面的程式碼會輸出什麼呢?
答案:10。
具體執行過程
- a 函式有一個形參 i,呼叫 a 函式時傳入實參 10,形參 i=10
- 接著定義一個同名的區域性變數 i,未賦值
- alert 輸出 10
2、案例二
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);
疑問:上面的程式碼又會輸出什麼呢?
答案:10,10,2,2
具體執行過程
- 函式有一個形參i,呼叫 a 函式時傳入實參 10,形參 i=10
- 第一個 alert 把形參 i 的值 10 輸出
- 第二個 alert 把 arguments[0] 輸出,應該也是 i
- 接著定義個區域性變數 i 並賦值為2,這時候區域性變數 i=2
- 第三個 alert 就把區域性變數 i 的值 2 輸出
- 第四個alert再次把 argumentsa[0] 輸出
3、案例三
2 function a(i) {
3 var i = i;
4 alert(i);
5 };
6 a(10)
疑問:上面的程式碼又又會輸出什麼呢?
答案:10
具體執行過程
- 第一句宣告一個與形參 i 同名的區域性變數 i,根據結果我們知道,後一個 i 是指向了
- 形參 i,所以這裡就等於把形參 i 的值 10 賦了區域性變數 i
- 第二個 alert 當然就輸出 10
4、案例四
2 var i=10;
3 function a() {
4 alert(i);
5 var i = 2;
6 alert(i);
7 };
8 a();
疑問:上面的程式碼又會輸出什麼呢?
答案:undefined, 2
具體執行過程
- 第一個alert輸出undefined
- 第二個alert輸出 2
看到上面的幾個例子,你可能會想到底是怎麼執行的呢?執行的細節又是怎麼樣的呢? JS 引擎的工作方式是怎樣的呢?
解析過程
1、執行順序
編譯型語言,編譯步驟分為:詞法分析、語法分析、語義檢查、程式碼優化和位元組生成。解釋型語言,通過詞法分析和語法分析得到語法分析樹後,就可以開始解釋執行了。這裡是一個簡單原始的關於解析過程的原理,僅作為參考,詳細的解析過程(各種JS引擎還有不同)還需要更深一步的研究
javascript的執行過程,如果一個文件流中包含多個script程式碼段(用script標籤分隔的js程式碼或引入的js檔案),它們的執行順序是:
- 步驟1. 讀入第一個程式碼段(js執行引擎並非一行一行地執行程式,而是一段一段地分析執行的)
- 步驟2. 做詞法分析和語法分析,有錯則報語法錯誤(比如括號不匹配等),並跳轉到步驟5
- 步驟3. 對【var】變數和【function】定義做“預解析“(永遠不會報錯的,因為只解析正確的宣告)
- 步驟4. 執行程式碼段,有錯則報錯(比如變數未定義)
- 步驟5. 如果還有下一個程式碼段,則讀入下一個程式碼段,重複步驟2
- 步驟6. 結束
2、特殊說明
全域性域(window)域下所有JS程式碼可以被看成是一個“匿名方法“,它會被自動執行,而此“匿名方法“內的其它方法則是在被顯示呼叫的時候才被執行
3、關鍵步驟
上面的過程,我們主要是分成兩個階段
- 解析:就是通過語法分析和預解析構造合法的語法分析樹。
- 執行:執行具體的某個function,JS引擎在執行每個函式例項時,都會建立一個執行環境(ExecutionContext)和活動物件(activeObject)(它們屬於宿主物件,與函式例項的生命週期保持一致)
相關文章
- 深入理解javascript原型和閉包(15)——閉包JavaScript原型
- 理解Javascript的閉包JavaScript
- javascript閉包簡單程式碼例項JavaScript
- 理解JavaScript 閉包JavaScript
- 理解 JavaScript 閉包JavaScript
- 對javascript閉包的理解JavaScript
- javascript閉包的個人理解JavaScript
- 理解 JavaScript 中的閉包JavaScript
- 全面理解Javascript閉包和閉包的幾種寫法及用途JavaScript
- javascript閉包的應用簡單程式碼例項JavaScript
- 深入理解javascript原型和閉包系列JavaScript原型
- 深入理解javascript原型和閉包(10)——thisJavaScript原型
- 面試:對javascript的閉包的理解面試JavaScript
- [JavaScript閉包]Javascript閉包的判別,作用和示例JavaScript
- 深入理解javascript原型和閉包(17)——補thisJavaScript原型
- 深入理解javascript原型和閉包(完結)JavaScript原型
- 閉包程式碼例項演示
- 深入理解javascript原型和閉包(16)——完結JavaScript原型
- 深入理解javascript原型和閉包(6)——繼承JavaScript原型繼承
- 深入理解javascript原型和閉包(5)——instanceofJavaScript原型
- 深入理解javascript原型和閉包(3)——prototype原型JavaScript原型
- 深入理解javascript原型和閉包(7)——原型的靈活性JavaScript原型
- 【譯】理解JavaScript閉包——新手指南JavaScript
- 深入理解javascript原型和閉包(4)——隱式原型JavaScript原型
- JS作用域與閉包--例項JS
- python閉包詳解(例項)Python
- JavaScript閉包原理與用法例項JavaScript
- 深入理解javascript原型和閉包(2)——函式和物件的關係JavaScript原型函式物件
- 深入理解javascript原型和閉包(12)——簡介【作用域】JavaScript原型
- 深入理解javascript系列(七):閉包(1)JavaScript
- 深入理解javascript系列(八):閉包(2)JavaScript
- 閉包用法結合例項詳解
- JavaScript 的閉包JavaScript
- javascript閉包用法例項程式碼分析JavaScript
- 理解“閉包”
- 理解閉包
- PHP 閉包的理解PHP
- js閉包的理解JS