總結
for..of適用遍歷數/數組對象/字符串/map/set等擁有迭代器對象的集合.但是不能遍歷對象,因為沒有迭代器對象.與forEach()不同的是,它可以正確響應break、continue和return語句。
for-of循環不支持普通對象,但如果你想迭代一個對象的屬性,你可以用for-in循環(這也是它的本職工作)或內建的Object.keys()方法。
for in遍歷的是數組的索引(即鍵名),而for of遍歷的是數組元素值。for of遍歷的只是數組內的元素,而不包括數組的原型屬性method和索引name。
forEach(value,index,Array)不能同時遍歷多個集合,在遍歷的時候無法修改和刪除集合數據,方法不能使用break,continue語句跳出循環,或者使用return從函數體返回,對於空數組不會執行回調函數。
forEach與for當循環遍歷為空的數組時,forEach會跳過為空的值,for不會跳過為空的數據,會直接顯示undefined。兩者都能識別出NULL。
forEach()
被調用時,不會改變原數組,也就是調用它的數組(盡管 callback
函數在被調用時可能會改變原數組)。
具體區別如下:
FOR
var arrList = [1,2,3,4,5,6]
for(var i = 0;i < arrList.length ; i++){
console.log(arrList[i]);
}
FOR-IN
語法
for (variable in object)
statement
-
variable
在每次迭代時,variable會被賦值為不同的屬性名。
-
object
非Symbol類型的可枚舉屬性被迭代的對象。
描述
for...in
循環只遍歷可枚舉屬性(包括它的原型鏈上的可枚舉屬性)。像 Array
和 Object
使用內置構造函數所創建的對象都會繼承自Object.prototype
和String.prototype
的不可枚舉屬性,例如 String
的 indexOf()
方法或 Object
的toString()
方法。循環將遍歷對象本身的所有可枚舉屬性,以及對象從其構造函數原型中繼承的屬性(更接近原型鏈中對象的屬性覆蓋原型屬性)。
舉例
/*
FOR..IN語句遍歷數組
*/
Array.prototype.method=function(){
console.log(this.length);
}
var myArray=[1,2,4]
myArray.name="數組"
for (var index in myArray) {
console.log(myArray[index]);
}
/*
輸出結果順序不唯一。輸出的結果包含如下:
1
2
4
數組
ƒ (){
console.log(this.length);
}
*/
/*
FOR..IN語句遍歷對象
*/
Object.prototype.method=function(){
console.log(this);
}
var myObject={
a:1,
b:2,
c:3
}
for (var key in myObject) {
console.log(key);
}
/*
輸出結果順序不唯一。輸出的結果包含如下:
a
b
c
method
1- for in 可以遍歷到myObject的原型方法method,如果不想遍歷原型方法和屬性的話,可以在循環內部判斷一 下,hasOwnPropery方法可以判斷某屬性是否是該對象的實例屬性.
2- 通過ES5的Object.keys(myObject)獲取對象的實例屬性組成的數組,不包括原型方法和屬性.
*/
for (var key in myObject) {
if(myObject.hasOwnProperty(key)){
console.log(key);
}
}
/*
輸出結果順序不唯一。輸出的結果包含如下:
a
b
c
*/
注意事項
-
FOR..IN語句遍歷的是索引index(鍵名)為字符串型數字,不能直接進行幾何運算。
-
使用for in會遍歷數組所有的可枚舉屬性,包括原型。例如上述案例的原型方法method和name屬性,所以for in更適合遍歷對象,不要使用for in遍歷數組。
刪除,添加或者修改屬性
for...in
循環以任意序迭代一個對象的屬性(請參閱delete
運算符,了解為什么不能依賴於迭代的表面有序性,至少在跨瀏覽器設置中)。如果一個屬性在一次迭代中被修改,在稍后被訪問,其在循環中的值是其在稍后時間的值。一個在被訪問之前已經被刪除的屬性將不會在之后被訪問。在迭代進行時被添加到對象的屬性,可能在之后的迭代被訪問,也可能被忽略。
通常,在迭代過程中最好不要在對象上進行添加、修改或者刪除屬性的操作,除非是對當前正在被訪問的屬性。這里並不保證是否一個被添加的屬性在迭代過程中會被訪問到,不保證一個修改后的屬性(除非是正在被訪問的)會在修改前或者修改后被訪問,不保證一個被刪除的屬性將會在它被刪除之前被訪問。
FOR-OF
for...of
語句在可迭代對象(包括 Array
,Map
,Set
,String
,TypedArray
,arguments 對象等等)上創建一個迭代循環,調用自定義迭代鈎子,並為每個不同屬性的值執行語句。不建議遍歷原有的原生對象。
語法
for (variable of iterable) {
//statements
}
-
variable
在每次迭代中,將不同屬性的值分配給變量。
-
iterable
被迭代枚舉其屬性的對象。
示例
/*
FOR..OF語句遍歷數組
*/
var myArray=[1,2,4,5,6,7,8]
for (var index of myArray) {
console.log(index);
}
/*
輸出結果順序唯一。輸出的結果如下:
1
2
4
5
6
7
8
*/
FOREACH
語法
arr.forEach(callback(currentValue [, index [, array]])[, thisArg]);
參數
-
callback
為數組中每個元素執行的函數,該函數接收三個參數:
currentValue
數組中正在處理的當前元素。index
可選數組中正在處理的當前元素的索引。array
可選forEach()
方法正在操作的數組。 -
thisArg
可選可選參數。當執行回調函數
callback
時,用作this
的值。
返回值
undefined
描述
forEach()
方法按升序為數組中含有效值的每一項執行一次 callback
函數,那些已刪除或者未初始化的項將被跳過(例如在稀疏數組上)。
舉例
/*
數組中未定義或者undefined數據的情況。
*/
const arraySparse = [1,3,,7];
let forCallbackRuns = 0;
let forEachCallbackRuns = 0;
arraySparse.forEach(function(element){
console.log(element);
forEachCallbackRuns++;
});
console.log("forEachCallbackRuns: ", forEachCallbackRuns);
/*
1
3
7
numCallbackRuns: 3
*/
for(var i = 0; i < arraySparse.length ; i++){
console.log(arraySparse[i]);
forCallbackRuns++;
}
console.log("forCallbackRuns: ", forCallbackRuns);
/*
1
3
undefined
7
forCallbackRuns: 4
*/
/*
數組中含有null數據的情況。
*/
const arraySparse = [1,3,null,7];
let forCallbackRuns = 0;
let forEachCallbackRuns = 0;
arraySparse.forEach(function(element){
console.log(element);
forEachCallbackRuns++;
});
console.log("forEachCallbackRuns: ", forEachCallbackRuns);
/*
1
3
null
7
forEachCallbackRuns: 4
*/
for(var i = 0; i < arraySparse.length ; i++){
console.log(arraySparse[i]);
forCallbackRuns++;
}
console.log("forCallbackRuns: ", forCallbackRuns);
/*
1
3
null
7
forCallbackRuns: 4
*/
注意
除了拋出異常以外,沒有辦法中止或跳出 forEach()
循環。如果你需要中止或跳出循環,forEach()
方法不是應當使用的工具。
若你需要提前終止循環,你可以使用:
- 一個簡單的 for 循環
- for...of / for...in 循環
Array.prototype.every()
Array.prototype.some()
Array.prototype.find()
Array.prototype.findIndex()
這些數組方法則可以對數組元素判斷,以便確定是否需要繼續遍歷:
譯者注:只要條件允許,也可以使用 filter()
提前過濾出需要遍歷的部分,再用 forEach()
處理。
參考資料鏈接
作者:Haiya_32ef 鏈接:https://www.jianshu.com/p/c43f418d6bf0
作者:weixin_34128411 鏈接:https://blog.csdn.net/weixin_34128411/article/details/94279246