(之前一直沒怎么注意數組循環,今天做一道題時,用到forEach循環發現它並沒有按照我想象的樣子執行,總結一下數組循環)
一.第一種方法就是for()循環
for( var index = 0; index < array.length; i ++){}
這種方法很常見,各個語言都有,這里就不再贅述
二.es5新增加的迭代方法(every,filter,forEach,map,some)
這些方法都接收兩個參數,1)在每一項上可運行的函數(傳入的函數接受三個參數:a. 數組項的值;b. 該項在數組中的位置; c. 數組本身);2)(可選)運行該函數的作用域——影響this的值。
語法:以forEach為例,其他類似
array.forEach(callback [, thisArg])
/**
*callback為要執行的回調函數,thisArg為綁定的this若未傳參,*callback
的this
值在非嚴格模式下將是全局對象,嚴格模式下為undefined
*/
var nums = [3, 2, 3, 4] nums.forEach(function(value, index, array){ //執行某些操作 }) /** *其中匿名函數為每一項要執行的函數;thisArg省略 * 匿名函數中 value為每一項的值,如3,2,3,4 * index為每一項的位置即索引,如0,1,2,3 *array為數組本身,如nums
*
*thisArg省略 */
1) every()方法:
測試數組中所有元素是否都通過指定函數的測試,若有一項返回false即返回false;
every方法為元素的每個元素執行一次callback函數(不包括通過某些方法刪除或者未定義的項,值定義為undefined的項除外),直到找到一個使callback返回false(可轉化為false的值),跳出迭代並返回false。否則(所有元素均返回true)返回true。
every方法遍歷到的元素為第一次調用callback那一個的值,之后添加的值不會被訪問到。
function isBigEnough(elemen) { return (element >= 10); } var passed = [12, 5, 8, 130, 44].every(isBigEnough); // passed is false passed = [12, 54, 18, 130, 44].every(isBigEnough); // passed is true
var a = [1, 2, 3,, 4].every (function(value){ console.log(value) return value })//1,2,3,4 console.log(a)//true a = [1, 2, 3, undefined,4].every (function(value){ console.log(value) return value })//1,2,3,undefind console.log(a)//false
2)filter()方法:
使用指定的函數測試所有的元素,創建並返回一個包含所有通過測試的元素的新數組
filter為數組中的每個元素調用一次callback(不包括通過某些方法刪除或者未定義的項,值定義為undefined的項除外),並利用所有callback返回true或等價於true的元素創建一個新數組,未通過callback測試的元素會被跳過,不會包含在新數組里。
var a = [1, 2, 3, 7,4].filter(function(value){ return value > 4 }) console.log(a)//[7]
3)forEach()方法:
forEach按升序為數組中含有相知的每一項執行一次callback函數(不包括通過某些方法刪除或者未定義的項,值定義為undefined的項除外)
forEach遍歷的范圍在第一次調用 callback 前就會確定。調用forEach后添加到數組中的項不會被 callback 訪問到。如果已經存在的值被改變,則傳遞給 callback 的值是 forEach遍歷到他們那一刻的值。已刪除的項不會被遍歷到。如果已訪問的元素在迭代時被刪除了(例如使用 shift()
) ,之后的元素將被跳過 。總是返回undefined,不能鏈式調用。
沒有辦法中止或者跳出 forEach 循環,除了拋出一個異常。如果你需要這樣,使用forEach()方法是錯誤的,你可以用一個簡單的循環作為替代
function logArrayElements(element, index, array) { console.log("a[" + index + "] = " + element); } // 注意索引2被跳過了,因為在數組的這個位置沒有項 [2, 5, ,9].forEach(logArrayElements); // a[0] = 2 // a[1] = 5 // a[3] = 9 [2, 5,"" ,9].forEach(logArrayElements); // a[0] = 2 // a[1] = 5 // a[2] = // a[3] = 9 [2, 5, undefined ,9].forEach(logArrayElements); // a[0] = 2 // a[1] = 5 // a[2] = undefined // a[3] = 9 let xxx; // undefined [2, 5, xxx ,9].forEach(logArrayElements); // a[0] = 2 // a[1] = 5 // a[2] = undefined // a[3] = 9
如果數組在迭代時被修改了,則其他元素會被跳過。
下面的例子輸出"one", "two", "four"。當到達包含值"two"的項時,整個數組的第一個項被移除了,這導致所有剩下的項上移一個位置。因為元素 "four"現在在數組更前的位置,"three"會被跳過。 forEach()
不會在迭代之前創建數組的副本。
var words = ["one", "two", "three", "four"]; words.forEach(function(word) { console.log(word); if (word === "two") { words.shift(); } }); // one // two // four
4) map()方法:
為數組每一項(不包括通過某些方法刪除或者未定義的項,值定義為undefined的項除外)執行一個指定函數,返回一個新數組,每個元素都是回調函數的結果
使用 map 方法處理數組時,數組元素的范圍是在 callback 方法第一次調用之前就已經確定了。在 map 方法執行的過程中:原數組中新增加的元素將不會被 callback 訪問到;若已經存在的元素被改變或刪除了,則它們的傳遞到 callback 的值是 map 方法遍歷到它們的那一時刻的值;而被刪除的元素將不會被訪問到。
var numbers = [1, 4, 9]; var roots = numbers.map(Math.sqrt); /* roots的值為[1, 2, 3], numbers的值仍為[1, 4, 9] */
5)some()方法:
測試數組中某些元素是否通過指定函數的測試,若有一項返回true即返回true
some為數組中的每一個元素執行一次 callback函數,直到找到一個使得 callback 返回一個“真值”(即可轉換為布爾值 true 的值),停止迭代並返回true;否則(所有元素均為false),返回false。
var a = [1, 2, 3, 7,4].some (function(value){ return value > 8 }) console.log(a)//false a = [1, 2, 3, 9,4].some (function(value){ return value > 8 }) console.log(a)//true