javascript foreach用法 - For-each在JavaScript中的數組?


14 Answers

編輯 :這個答案毫無希望地過時了。 有關更現代的方法,請查看陣列上可用的方法 。 感興趣的方法可能是:

  • 的forEach
  • 地圖
  • 過濾
  • 壓縮
  • 降低
  • 一切
  • 一些

JavaScript迭代數組的標準方法是-loop:

var length = arr.length,
    element = null;
for (var i = 0; i < length; i++) {
  element = arr[i];
  // Do something with element
}

但請注意,只有擁有密集數組且每個索引都被一個元素佔用時,此方法才有用。 如果數組是稀疏的,那麼你可能會遇到這種方法的性能問題,因為你會迭代很多在數組中不存在的索引。 在這種情況下, for .. in -loop可能是一個更好的主意。 但是 ,您必須使用適當的安全措施來確保僅對數組的所需屬性(即數組元素)起作用,因為for..in -loop也將在舊版瀏覽器中枚舉,或者如果附加屬性定義為enumerable

ECMAScript 5中 ,陣列原型上將有一個forEach方法,但在舊版瀏覽器中不支持它。 因此,為了能夠始終如一地使用它,您必須具有支持它的環境(例如,服務器端JavaScript的Node.js ),或使用“Polyfill”。 然而,Polyfill對於這個功能是微不足道的,因為它使代碼更容易閱讀,所以它是一個很好的polyfill。

Question

foreach javascript教學

如何使用JavaScript循環遍歷數組中的所有條目?

我以為它是這樣的:

forEach(instance in theArray)

其中theArray是我的數組,但這似乎是不正確的。




向後循環

我認為反向循環值得一提:

for (var i = array.length; i--; ) {
     // process array[i]
}

好處:

  • 您不需要聲明臨時len變量,也不需要在每次迭代時與array.length進行比較,其中任何一個都可能是一個小時優化。
  • 以相反的順序從DOM中刪除兄弟姐妹通常更有效 。 (瀏覽器需要減少內部數組中元素的移動。)
  • 如果在循環時,在索引i處或之後修改數組 (例如,在array[i]刪除或插入項目),則前向循環將跳過向左移動到位置i的項目 ,或者重新處理i那個向右移動的物品。 在傳統的for循環中,您可以更新i以指向需要處理的下一個項目 - 1,但簡單地反轉迭代方向通常是一種更簡單更優雅的解決方案
  • 類似地,當修改或移除嵌套的 DOM元素時,反向處理可以避免錯誤 。 例如,在處理子節點之前,請考慮修改父節點的innerHTML。 到達子節點時,它將與DOM分離,在寫入父內部HTML時,已被新創建的子節點替換。
  • 鍵入和讀取的時間比其他一些可用選項 。 雖然它失去了forEach()和ES6的for ... of

缺點:

  • 它以相反的順序處理項目。 如果您從結果中構建新數組,或在屏幕上打印內容, 則輸出將相對於原始順序反轉
  • 為了保留他們的順序,重複地將兄弟姐妹插入DOM作為第一個孩子的效率較低 。 (瀏覽器將不得不改變方向。)要按順序有效地創建DOM節點,只需循環前進並正常追加(並使用“文檔片段”)。
  • 反向循環讓初級開發人員感到困惑 。 (你可以認為這是一個優勢,取決於你的前景。)

我應該經常使用它嗎?

一些開發人員默認使用reverse for循環,除非有充分的理由向前循環。

雖然性能提升通常微不足道,但它有點尖叫:

“只需對列表中的每個項目執行此操作,我不關心訂單!”

然而,在實踐中,這實際上並不是意圖的可靠指示,因為它與您關心訂單的情況無法區分,並且確實需要反向循環。 因此實際上需要另一個構造來準確表達“不關心”的意圖,這在大多數語言中目前都不可用,包括ECMAScript,但可以調用,例如, forEachUnordered()

如果順序無關緊要, 效率是一個問題(在遊戲或動畫引擎的最內層循環中),那麼使用反向循環作為你的首選模式是可以接受的。 請記住,在現有代碼看到反向循環並不一定意味著訂單無關緊要!

最好使用forEach()

一般來說,對於更高級別的代碼,其中清晰度和安全性是更大的問題,我建議使用Array::forEach作為默認模式:

  • 很清楚閱讀。
  • 它表明不會在塊中移位(這總是可能會隱藏在long forwhile循環中。)
  • 它為您提供了一個免費的閉包範圍。
  • 它減少了局部變量的洩漏以及外部變量的意外碰撞(和突變)。

然後,當你在代碼中看到反向for循環時,這是一個暗示它被推翻的原因很充分(可能是上述原因之一)。 並且看到傳統的前向循環可能表明可能發生轉移。

(如果對意圖的討論對你沒有意義,那麼你和你的代碼可能會受益於觀看Crockford關於編程風格和你的大腦的講座。)

它是如何工作的?

for (var i = 0; i < array.length; i++) { ... }   // Forwards

for (var i = array.length; i--; )    { ... }   // Reverse

您會注意到i--是中間子句(我們通常會看到比較),最後一個子句是空的(我們通常會看到i++ )。 這意味著我 - 也被用作繼續的條件 。 至關重要的是,它會每次迭代之前執行並檢查。

  • 它如何從array.length開始而不爆炸?

    因為i-- 每次迭代之前運行,所以在第一次迭代時我們實際上將訪問array.length - 1處的項目,這避免了Array-out-of-bounds undefined項目的任何問題。

  • 為什麼它不會在索引0之前停止迭代?

    當條件i--計算為假值(當它產生0時),循環將停止迭代。

    訣竅是,與--i不同,尾隨的i--運算符遞減i但在遞減之前產生值。 你的控制台可以證明:

    > var i = 5; [i, i--, i];

    [5, 5, 4]

    所以在最後一次迭代中, 之前是1並且i--表達式將其更改為0但實際上產生1 (真實),因此條件通過。 在下一次迭代中, i--i更改為-1但產生0 (falsey),導致執行立即退出循環的底部。

    在循環的傳統轉發中, i++++i是可以互換的(正如Douglas Crockford指出的那樣)。 但是在反向for循環中,因為我們的減量也是我們的條件表達式,所以如果我們想在索引0處理項目,我們必須堅持使用i--

瑣事

有些人喜歡在反面畫一個小箭頭,然後以眨眼結束:

for (var i = array.length; i --> 0 ;) {

積分轉到WYL,向我展示反向循環的好處和恐怖。




如果要循環遍歷數組,請使用標準的三部分for循環。

for (var i = 0; i < myArray.length; i++) {
    var arrayItem = myArray[i];
}

您可以通過緩存myArray.length或向後迭代來獲得一些性能優化。




如果你不介意清空數組:

var x;

while(x = y.pop()){ 

    alert(x); //do something 

}

x將包含y的最後一個值,它將從數組中刪除。 你也可以使用shift()來提供和刪除y中的第一項。




現在一個簡單的解決方案是使用underscore.js庫。它提供了許多有用的工具,例如each並且會自動將作業委託給本機(forEach如果可用)。

CodePen如何工作的示例是:

var arr = ["elemA", "elemB", "elemC"];
_.each(arr, function(elem, index, ar)
{
...
});

也可以看看

  • Array::forEach
  • for_each...in(MDN)中,它被解釋for each (variable in object)為作為ECMA-357(EAX)標準的一部分被棄用。
  • for...of(MDN)描述了迭代使用的下一種方式,for (variable of object)作為Harmony(ECMAScript 6)提案的一部分。



有三種實現方式foreachjQuery如下。

var a = [3,2];

$(a).each(function(){console.log(this.valueOf())}); //Method 1
$.each(a, function(){console.log(this.valueOf())}); //Method 2
$.each($(a), function(){console.log(this.valueOf())}); //Method 3






在JavaScript 中有幾種循環數組的方法,如下所示:

因為 - 這是最常見的一個。用於循環的完整代碼塊

var languages = ["JAVA", "JavaScript", "C#", "Python"];
var i, len, text;
for (i = 0, len = languages.length, text = ""; i < len; i++) {
    text += languages[i] + "<br>";
}
document.getElementById("example").innerHTML = text;
<p id="example"></p>

while - 循環而條件通過。它似乎是最快的循環

var text = "";
var i = 0;
while (i < 10) {
    text +=  i + ") something<br>";
    i++;
}
document.getElementById("example").innerHTML = text;
<p id="example"></p>

do / while - 在條件為真時循環遍歷代碼塊,將至少運行一次

var text = ""
var i = 0;
do {
    text += i + ") something <br>";
    i++;
}
while (i < 10);
document.getElementById("example").innerHTML = text;
<p id="example"></p>

功能循環 - ,forEachmapfilterreduce(他們通過循環功能,但如果你需要做的事情與你的陣列等使用

// For example, in this case we loop through the number and double them up using the map function
var numbers = [65, 44, 12, 4];
document.getElementById("example").innerHTML = numbers.map(function(num){return num * 2});
<p id="example"></p>

有關數組上函數編程的更多信息和示例,請參閱博客文章JavaScript中函數編程:map,filter和reduce




ECMAScript5(Javascript上的版本)與Arrays一起使用。

forEach - 遍歷數組中的每個項目,並為每個項目執行所需的任何操作。

['C', 'D', 'E'].forEach(function(element, index) {
  console.log(element + " is the #" + (index+1) + " in musical scale");
});

// Output
// C is the #1 in musical scale
// D is the #2 in musical scale
// E is the #3 in musical scale

萬一,對使用一些內置功能的陣列操作更感興趣。

map - 它使用回調函數的結果創建一個新數組。當您需要格式化數組的元素時,可以使用此方法。

// Let's upper case the items in the array
['bob', 'joe', 'jen'].map(function(elem) {
  return elem.toUpperCase();
});

// Output: ['BOB', 'JOE', 'JEN']

reduce - 正如名稱所說,它通過調用傳入currenct元素的給定函數和先前執行的結果將數組減少為單個值。

[1,2,3,4].reduce(function(previous, current) {
  return previous + current;
});
// Output: 10
// 1st iteration: previous=1, current=2 => result=3
// 2nd iteration: previous=3, current=3 => result=6
// 3rd iteration: previous=6, current=4 => result=10

every - 如果數組中的所有元素都在回調函數中傳遞測試,則返回true或false。

// Check if everybody has 18 years old of more.
var ages = [30, 43, 18, 5];  
ages.every(function(elem) {  
  return elem >= 18;
});

// Output: false

filter - 非常類似於除過濾器之外的每個過濾器返回一個數組,其中的元素返回true給定的函數。

// Finding the even numbers
[1,2,3,4,5,6].filter(function(elem){
  return (elem % 2 == 0)
});

// Output: [2,4,6]

希望這會有用。




jQuery方式使用$.map

var data = [1, 2, 3, 4, 5, 6, 7];

var newData = $.map(data, function(element) {
    if (element % 2 == 0) {
        return element;
    }
});

// newData = [2, 4, 6];



lambda語法通常不適用於IE 10或更低版本。

我經常使用

[].forEach.call(arrayName,function(value,index){
    console.log("value of the looped element" + value);
    console.log("index of the looped element" + index);
});


If you are a jQuery Fan and already have a jQuery file running, you should reverse the positions of the index and value parameters

$("#ul>li").each(function(**index,value**){
    console.log("value of the looped element" + value);
    console.log("index of the looped element" + index);
});



for(let i=0;i<theArray.length;i++){
  console.log(i); //i will have the value of each index
}



如果你想使用forEach()它,它看起來像 -

theArray.forEach ( element => { console.log(element); });

如果你想使用for()它,它看起來像 -

for(let idx = 0; idx < theArray.length; idx++){ let element = theArray[idx]; console.log(element); }




摘要:

在遍歷數組時,我們通常可能希望實現以下目標之一:

  1. 我們想迭代數組並創建新數組:

    Array.prototype.map

  2. 我們想迭代數組而不創建新數組:

    Array.prototype.forEach

    for..of

在JS中,有許多方法可以實現這兩個目標。然而,有些人比其他人更有條理。下面你可以找到一些常用的方法(最方便的imo)來完成javascript中的數組迭代。

創建新數組: Map

map()是一個位於其上的函數Array.prototype,可以轉換數組的每個元素,然後返回一個數組。map()將回調函數作為參數,並按以下方式工作:

let arr = [1, 2, 3, 4, 5];

let newArr = arr.map((element, index, array) => {
  return element * 2;
})

console.log(arr);
console.log(newArr);

我們map()作為參數傳遞的回調是針對每個元素執行的。然後返回一個與原始數組長度相同的數組。在這個新的數組元素由作為參數傳入的回調函數轉換map()

在不同的差異map和其他循環機制,就像forEach和一個for..of循環是map回報作為新的數組和離開舊陣列完好(除了這樣想,如果你明確地操縱它splice)。

另請注意,map函數的回調提供了當前迭代的索引號作為第二個參數。此外,第三個參數提供了map被調用的數組。有時這些屬性非常有用。

循環使用 forEach

forEach是一個函數,它位於Array.prototype一個回調函數作為參數。然後它為數組中的每個元素執行此回調函數。與map()函數相反,forEach函數不返回任何內容(undefined)。例如:

let arr = [1, 2, 3, 4, 5];

arr.forEach((element, index, array) => {

  console.log(element * 2);

  if (index === 4) {
    console.log(array)
  }
  // index, and oldArray are provided as 2nd and 3th argument by the callback

})

console.log(arr);

就像map函數一樣,forEach回調提供了當前迭代的索引號作為第二個參數。第三個參數也提供了forEach被調用的數組。

循環使用元素 for..of

所述for..of的循環遍歷的陣列(或任何其他迭代的對象)的每一個元素。它的工作方式如下:

let arr = [1, 2, 3, 4, 5];

for(let element of arr) {
  console.log(element * 2);
}

在上面的例子中element代表一個數組元素,arr是我們想要循環的數組。並非名稱element是任意的,我們可以選擇任何其他名稱,如'el'或更適用的聲明。

不要將for..in循環與for..of循環混淆。for..in將循環遍歷數組的所有可枚舉屬性,而for..of循環將僅循環遍歷數組元素。例如:

let arr = [1, 2, 3, 4, 5];

arr.foo = 'foo';

for(let element of arr) {
  console.log(element);
}

for(let element in arr) {
  console.log(element);
}




Related