簡體   English   中英

如果被推送的元素不是原始元素,為什么JavaScript Array.push不使用變量

[英]Why does JavaScript Array.push not use variable if the pushed element is not a primitive

考慮這個經典的JavaScript閉包功能。 我了解封包的展示方式。 我知道內部函數會關閉變量i,即3。

我不明白的是為什么數組應該包含變量i,而我們所做的只是將函數推入數組中,而數組中我有一個來自for循環的值。

 function buildFunctions() { var arr = []; for (var i = 0; i < 3; i++) { arr.push(function() { console.log(i) }) } return arr; } var fs = buildFunctions(); // [function(){console.log(1)}, ...and so on] //not [function(){console.log(i)} ...and so on] fs[0](); // outputs 3 fs[1](); // 3 fs[2](); // 3 

否則,這將返回數組的正確(imo)內容:

function buildFunctions() {
   var arr = [];
   for (var i = 0; i < 3; i++) {
      arr.push(i)
   }
   return arr; // [0, 1, 2]
 }

arr.push(i)通過一個原始值到.push ,值012分別。 這里的值與i解除關聯; 你不推i ,你推012

arr.push(function () { console.log(i) })推送一個內部引用變量的函數。 在調用函數時,該變量的值恰好是3 (👈這是要理解的關鍵句子。)

請注意,推函數和推數字之間沒有根本區別。 兩者都簡單地通過值傳遞。 在一種情況下,值是一個數字,在另一種情況下,值是一個函數。 請參閱JavaScript是引用傳遞還是值傳遞語言?

我認為循環由於某種原因而增加了混亂。 如果展開該循環,則可能更直觀。

 function buildFunctions() { var arr = []; var i = 0; arr.push(function() { console.log(i) }) i++; arr.push(function() { console.log(i) }) i++; arr.push(function() { console.log(i) }) i++; return arr; } var fs = buildFunctions(); // [function(){console.log(1)}, ...and so on] //not [function(){console.log(i)} ...and so on] fs[0](); // outputs 3 fs[1](); // 3 fs[2](); // 3 

因此,您可以看到我們正在將三個函數推入數組,而在兩者之間,我們正在遞增i 您還可以看到所有三個函數都在“看”相同的i變量。

調用函數之前,不會讀取變量,因此,由於它們都在“看”相同的變量,因此最終調用它們時,它們自然會給出相同的結果。 而且由於在任何一次調用之前 i都增加了3倍,因此返回的值為3


作為練習,更改每個函數以在其中添加另一個i++ 您將看到,不僅它們都讀取同一個變量,而且它們都可以突變相同的變量。

當您調用該函數時, i的值將變為3 ,這是arr.push內部的函數arr.push引用的。

塊范圍let將給您預期的結果:

 function buildFunctions() { var arr = []; for (let i = 0; i < 3; i++) { arr.push(function() { console.log(i) }) } return arr; } var fs = buildFunctions(); // [function(){console.log(1)}, ...and so on] //not [function(){console.log(i)} ...and so on] fs[0](); // 0 fs[1](); // 1 fs[2](); // 2 

我不明白的是為什么數組應該包含變量i

沒有。

該數組包含三個函數。

這些函數中的每一個都關閉(相同)變量i 注: i沒有價值i的時間。

您調用任何一個函數( 在循環完成之后 )時,它們都會讀取該變量的值。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM