js 關於閉包與訪問陣列下標的老生常談

2021-07-11 21:29:16 字數 1181 閱讀 1700

閉包的問題,想必給學習js的新手們造成了成噸的暴擊,尤其是下面這個問題:

段落0段落1

段落2段落3

段落4這個**,我是在網上找的乙個典型問題,即所謂:閉包只能訪問到外部函式變數的最終值。

這個結論大家都已經知道,但到底為什麼,網上的說法大都比較複雜難懂。這裡我找了乙個比較簡單的方式,來解釋下。

先總結一句,即值傳遞和引用傳遞的區別。

先來看段簡單的**:

function a()

alert(res[0]);

} a();

這個**執行時, 會輸出0,那麼它正確的訪問了下標;

然後我們稍作改動:

function a();

}alert(res[0]);

} a();

這個時候,一般新手會認為,輸出0 或者5,其實都不對,正確答案是輸出一段匿名函式的**:function();

好,關鍵點來了! 為何在我們使用匿名函式後,會出來個這麼東西呢? 如果有c語音基礎的應該知道,那就是在傳遞函式時,並非值傳遞而是引用傳遞。也就是說,   res[i]=function();

這段**,會把值為匿名函式位址的指標傳遞給 變數res[i],而並非把i傳遞給res[i]。新人一般會誤把變數i和**執行劃等號,其實根本是不同的東西

那這會造成什麼後果?那就是res[i]變成了匿名函式的函式名了,對res[i]進行自呼叫的話:(res[0])();,就會出現,我們之前所討論的問題,那就是為什麼i變成了5:為什麼呢?很簡單,那就是每次呼叫匿名函式時,都會重新執行一遍匿名函式的**。也是說會重新根據作用域鏈來找i的值。而迴圈在輸出語句之前,迴圈結束,i自然變成了5,此時執行匿名函式的**,找到的自然是5;

值傳遞和引用傳遞是不一樣的,值傳遞的話,res[0]在記憶體中會直接儲存對應的變數i的值:0,而引用傳遞,則會讓res[0]去儲存一段**的位址即指標,每次訪問res[0],其實就等同於訪問匿名函式的執行結果。而迴圈在訪問之前就已經運算結束,i的值已經變成了5,自然就會輸出5了。

在讓我們來看最初的**:

document.getelementbyid("p"+i).οnclick=function() {

alert(i);

當觸發onclick時,其實不是簡單輸出變數i,而是去訪問匿名函式的**的執行結果。相當於是去訪問現在i的值,而不是過去那個迴圈中的i的值。 所以才會導致總是輸出i的最終值的結果。

關於js的閉包

要理解上面的問題,首先要理解清楚幾個概念 來自 閉包裡的微觀世界 區別就是值型別變數是可以直接訪問棧 stack 中的值 接下來的內容就是關於閉包的微觀世界 function a return b var c a 函式a執行後返回函式b,並將函式b賦給c c 輸出 1 本來這個地方變數i是定義在函式...

指標與陣列 指標訪問與下標訪問

指標與陣列下標訪問與指標訪問的區別如下 1 以指標形式訪問指標 p 4 指標p的位址為0x00415754,加上4個字元的偏移量後的新位址為0x00415758,然後取出新位址中的內容0x65 e 2 以下標形式訪問指標 p 4 編譯器將下標形式的操作解析為以指標形式的操作。首先取出 指標p的位址0...

Js閉包與迴圈

目標 點選任何乙個li,提示當前點選位置 1 先執行 1 位置,彈出5次警示框從0到4,執行的是for語句,i 在for內部已經變為5 2 li i 是獲取的li的htmlcollection物件,i i 相當於li.item i 3 為li i 繫結事件,li i onclick 實際上此時執行的...