最近的迭代方式甚多,老夫好累。
語句迭代
下述都是語句,所以可以在其中使用break
,continue
。
for
不說了,最基本的。
while
迭代次數(shù)不定時常用,略過。
for...in...
常用于迭代一個對象的可枚舉屬性(包含原型鏈上的)
也可以用來迭代數(shù)組,但是并不推薦這么做。
主要是有以下情況
1.數(shù)組原型或是數(shù)組本身有其他自定義的屬性,會一并輸出。
Array.prototype.foo = 1;
var a = [1, 2, 3,];
for (var x in a){
console.log(x)
} // 0,1,2,foo
2.數(shù)組是分散賦值的,輸出情況有誤
var a = [];
a[2] = 2;
for (var i = 0; i < a.length; i++) {
console.log(i,a[i])
}
// 0 undefined
// 1 undefined
// 2 2
for (var x in a){
console.log(x,a[x])
}
// 2 2
for...of...
for...of...是ES6的迭代語句,提供了一個統(tǒng)一的接口。可用于迭代Object
, Array
,Map
,Set
, 類數(shù)組對象string
,arguments
,DOM NodeList
以及 Generator
。
在ES6中,這些可迭代對象都有X.keys()
, X.values()
, X.entries()
,返回的是一個Iterator
對象,可用[...Result]的形式轉(zhuǎn)為數(shù)組。
TIP 迭代的是自身的,不含繼承的,可枚舉鍵名鍵值和鍵值對
Object目前還沒有這個接口,可用ES5的
Object.keys(obj)
,Object.values(obj)
,和Object.entries(obj)
代替,(其中values和entries是正在實(shí)驗中的屬性)返回一個數(shù)組。已提上ES7法案。
建議目前還是使用for...in或for..of Object.keys()進(jìn)行迭代(區(qū)別在于是否迭代原型鏈上的屬性)
在for...of 迭代時,除了Map默認(rèn)取entries(i是一個數(shù)組)Object,Array,Set都是默認(rèn)取values(i是對應(yīng)的值),
方法迭代
自帶了一些迭代方法。
注意的是這些是函數(shù),不能調(diào)用continue
或break
來跳出循環(huán)。
如果想實(shí)現(xiàn)continue效果,應(yīng)該對函數(shù)內(nèi)部return。
如果想實(shí)現(xiàn)break效果,可以利用throw錯誤提前結(jié)束循環(huán),但不如使用some,any方法或是直接使用for...of...循環(huán)
forEach
X.forEach(callback(value,key,X),this)。
遍歷每一項執(zhí)行一次callback值。
最常用的方法,需要注意的是:
var s = ['a',undefined,'b','c',null];
for(var i of s){
if(i == 'a') {
delete s[3];
s.push('d');
s[2] = 'bchange'
}
console.log(i)
}
var a= ['a',undefined,'b','c',null];
a.forEach((value,key)=>{
if(key== 0){
delete a[3];
a.push('d');
a[2] = 'bchange'
};
console.log(value,key)}
)
console.log(s,a)
輸出:
a undefined bchange undefined null d
a 0 undefined 1 bchange 2 null 4
["a", undefined, "bchange", 4: null, 5: "d"] ["a", undefined, "bchange", 4: null, 5: "d"]
var m = [];
m[2] = 'value2';
for(var i of m){
console.log(i)
}
m.forEach((value,key)=>{console.log(value,key)})
輸出
undefined undefined value2
value 2
var s = new Set(['a',undefined,'b','c',null]);
for(var i of s){
if(i == 'a') {
s.delete('c');
s.add('d');
}
console.log(i)
}
var a= new Set(['a',undefined,'b','c',null]);
a.forEach((value,key)=>{
if(key== 'a'){
a.delete('c');
a.add('d');
};
console.log(value)}
)
console.log([...s],[...a])
輸出
a undefined b null d
a undefined b null d
["a", undefined, "b", null, "d"] ["a", undefined, "b", null, "d"]
- 對于數(shù)組來說
- forEach遍歷的元素范圍在第一次調(diào)用 callback之前就已確定了。在調(diào)用都之后添加到數(shù)組中的元素不會被 callback訪問到。如果數(shù)組中存在的元素被更改,則他們傳入 callback的值是訪問到他們那一刻的值。那些被刪除的元素或從來未被賦值的元素將不會被訪問到。
- for...of則是會在調(diào)用中確定,對于已刪除或未賦值的元素,都會進(jìn)行遍歷,對于添加或是后來進(jìn)行修改的元素,會在迭代到該元素的那一刻前進(jìn)行判斷生效。
- 對于Map,Set來說
- 對于那些已經(jīng)被刪除的元素,forEach和for..of都不會執(zhí)行的(因為不像數(shù)組那樣還可以置為undefined),但是,對于元素是undefined的情況會執(zhí)行。
- 其余的都正常執(zhí)行(包括后添加的元素)。
every & some & filter & map
這兩個都是針對Array的。
- every
- 測試數(shù)組的所有元素是否都通過了指定函數(shù)的測試。
- 為數(shù)組中的每一個元素執(zhí)行一次 callback函數(shù),直到找到一個使得 callback 返回一個false的元素,如果發(fā)現(xiàn)了一個這樣的元素,every方法將會立即返回 false。否則返回true。
- 即callback中如果通過測試應(yīng)返回true,沒有返回false。
- some
- 測試數(shù)組中的某些元素是否通過了指定函數(shù)的測試。
- some為數(shù)組中的每一個元素執(zhí)行一次 callback函數(shù),直到找到一個使得 callback 返回一個“真值”。如果找到了這樣一個值,some將會立即返回 true。否則,some返回false。
- 即callback中如果通過測試應(yīng)返回true,沒有返回false。
- filter
- 使用指定的函數(shù)測試所有元素,并創(chuàng)建一個包含所有通過測試的元素(callback返回true)的新數(shù)組。
- map
- 返回一個由原數(shù)組中的每個元素調(diào)用一個指定方法后的返回值組成的新數(shù)組
- 都不會改變原數(shù)組。
- 都遍歷的元素范圍在第一次調(diào)用 callback之前就已確定了。在調(diào)用都之后添加到數(shù)組中的元素不會被 callback訪問到。如果數(shù)組中存在的元素被更改,則他們傳入 callback的值是訪問到他們那一刻的值。那些被刪除的元素或從來未被賦值的元素將不會被訪問到。