js 中for循環那些事

語法

for ([initialization]; [condition]; [final-expression]) {
    statement
}

initialization
一個表達式 (包含賦值語句) 或者變量聲明。典型地被用於初始化一個計數器。該表達式可使用var或let關鍵字聲明新的變量,使用var聲明的變量不是該循環的局部變量,而是與for循環處在一樣的做用域中。用let聲明的變量是語句的局部變量。該表達式的結果無心義。注意此處的let 和 var 聲明表達式的不一樣點express

condition
一個條件表達式被用於肯定每一次循環是否能被執行。若是該表達式的結果爲true, statement 將被執行。 這個表達式是可選的。若是被忽略,那麼就被認爲永遠爲真。若是計算結果爲假,那麼執行流程將被跳到for語句結構後面的第一條語句。
final-expression
每次循環的最後都要執行的表達式。執行時機是在下一次condition的計算以前。一般被用於更新或者遞增計數器變量。
statement
只要condition的結果爲true就會被執行的語句。 要在循環體內執行多條語句,使用一個塊語句({ ... })來包含要執行的語句。沒有任何語句要執行,使用一個空語句(;)。 可使用break 主動跳出循環數組

注意點:

  1. 初始化中使用var聲明的變量不是該循環的局部變量,而是與for循環處在一樣的做用域中,使用let聲明的則在局部變量中
  2. 初始化塊中的表達式都是能夠省略的,若是省略則須要在語句塊中設置跳出條件,避免進入死循環
  3. 在for循環內部使用異步函數、閉包等時的問題:

setTimeOut等異步函數時:閉包

var arr = [1,3,5,7,9];
for (var i = 0; i < arr.length-1; i++) {
    setTimeout(function() {
        console.log("循環的值:"+i);
        console.log("數組對應的值:"+arr[i]);
    }, 1000);
}

clipboard.png
存在閉包時:異步

function box() {
    var arr = [];
    for (var i = 0; i < 5; i++) {
        arr[i] = function () {
            return i;                            //因爲這個閉包的關係,他是循環完畢以後才返回,最終結果是4++是5
        }                                        //這個匿名函數裏面根本沒有i這個變量,因此匿名函數會從父級函數中去找i,
    }                                            //當找到這個i的時候,for循環已經循環完畢了,因此最終會返回5
    return arr;
}
let boxArr = box();
console.log(boxArr[0]())

clipboard.png

這時,會產生與咱們預期所想獲得的效果不一樣的結果,致使出現這種狀況的緣由主要是 for語句表達式中初始化中的變量不是該循環的局部變量(子做用域),而是與for循環處在一樣的做用域中(父做用域)。
所以,解決方案比較流行的有兩種:
第一種:使用let 替代 var 聲明for循環的表達式(推薦)函數

function box() {
    var arr = [];
    for (let i = 0; i < 5; i++) {
        arr[i] = function () {
            return i;                           
        }                                       
    }                                            
    return arr;
}
let boxArr = box();
console.log(boxArr[0]())

clipboard.png

var arr = [1,3,5,7,9];
for (let i = 0; i < arr.length-1; i++) {
    setTimeout(function() {
        console.log("循環的值:"+i);
        console.log("數組對應的值:"+arr[i]);
    }, 1000);
}

clipboard.png

第二種:使用自執行函數利用閉包特性來達到效果:spa

var arr = [1, 3, 5, 7, 9];
for (var i = 0; i < arr.length ; i++) {
    (j=>{
        setTimeout(() =>{
            console.log("循環的值:" + j);
            console.log("數組對應的值:" + arr[j]);
        }, 1000);
    })(i)
}

clipboard.png

function box() {
    var arr = [];
    for (var i = 0; i < 5; i++) {
        ((j)=>{
            arr[j] = ()=> j;
        })(i);
    }                                            
    return arr;
}
let boxArr = box();
console.log(boxArr[0]())
console.log(boxArr[1]())

clipboard.png

相關文章
相關標籤/搜索