JS中的一些遍歷方法
1、遍歷數組
以下遍歷方法中for循環性能最好,而且優化版for循環性能最高。只有forEach不能跳出循環。
在循環數組時,如果在循環過程中對數組進行了增刪改,那么在后面的每次循環中,進行操作的都是已經修改過后的數組。
let arr = ['a','b','c','d']; for (let i = 0; i < arr.length; i++) { const element = arr[i]; if(i ==0 || i ==1) { arr.splice(i, 1); } } console.log(arr); //此時輸出 ["b", "d"] 而不是 ["c", "d"],即實際上刪除了 a、c
1.1、for循環
該循環可以使用 break、continue 來跳出循環,若該循環放在函數體內則可以使用 return ,return 只能在函數體內使用。
var arr = [1,2,3] for(var i=0; i<arr.length; i++) { console.log(arr[i]) //1,2,3 } //優化版for循環,對于較大的數組優化比較明顯 for(var i=0,len = arr.length; i<len; i++) { console.log(arr[i]) //1,2,3 }
注意,以上循環是先判斷再執行,第一次執行也需判斷
1.2、forEach循環
forEach循環每個元素是值。
該循環無法中途跳出循環,break、continue、return都無法使用。
var arr = [1,2,3] arr.forEach(function(value, index, arr){ console.log(value, index, arr) }) //value:必需,當前數組元素的值 //index:可選,當前元素的索引 //arr:可選,當前元素所屬的數組對象
1.3、for...in循環
for...in循環每個元素是索引,該循環效率比較低。for...in 循環不太適用于遍歷數組,主要是為遍歷對象而設計的。
該循環可以使用 break、continue 來跳出循環,若該循環放在函數體內則也可以使用 return 。
//用于數組 var arr = [1,2,3,4] for (var i in arr) { console.log(arr[i]) //1,2,3,4 } //用于對象 var obj = {'a':1, 'b':2, 'c':3} for (var j in obj) { console.log(obj[j]) //1,2,3 }
1.4、for...of循環 (es6新引入)
for...of循環每個元素是值。該循環不支持對象。
該循環可以使用 break、continue 來跳出循環,若該循環放在函數體內則也可以使用 return。
var arr = [1,2,3] for (var value of arr) { console.log(value) } for (var value of arr) { if(value> 2) break; //break跳出循環 console.log(value) } //輸出:1 2
1.5、map循環
map 循環可以遍歷數組
map的回調函數中支持 return返回值,return 后面的值將返回作為新數組的元素,原數組不會改變。
array.map(function(val,index,arr){})
let arr = ['a','b','c']; arr.map(function(val,index,arr){ console.log(val,index,arr); // ["a", "b", "c"] }) let arr2 = arr.map(function(val,index,arr){ return 'new '+val; }) console.log(arr2) //["new a", "new b", "new c"]
2、遍歷對象
2.1、可枚舉性的概念
對象的每個屬性都有一個描述對象(Descriptor),用來控制該屬性的行為。Object.getOwnPropertyDescriptor方法可以獲取該屬性的描述對象。
let obj = { foo: 123 };
Object.getOwnPropertyDescriptor(obj, 'foo')
// {
// value: 123,
// writable: true,
// enumerable: true,
// configurable: true
// }
描述對象的enumerable屬性,稱為“可枚舉性”,如果該屬性為false,某些操作比如一些遍歷操作會忽略當前屬性。
目前,有四個操作會忽略enumerable為false的屬性。
for...in循環:只遍歷對象自身的和繼承的可枚舉的屬性。Object.keys():返回對象自身的所有可枚舉的屬性的鍵名。JSON.stringify():只串行化對象自身的可枚舉的屬性。Object.assign():忽略enumerable為false的屬性,只拷貝對象自身的可枚舉的屬性。
2.2、for...in方法遍歷
該遍歷方法輸出的是對象自身的屬性以及原型鏈上可枚舉的屬性。不含Symbol屬性。(包含所有可枚舉的)(不含 Symbol 的)
var obj = { 'name': "wen", 'age': '12', }; Object.prototype.country = 'china'; //在原型鏈上添加屬性,默認的可枚舉性是 true console.log(obj); for (var index in obj) { console.log(index,obj[index]) }
2.2、利用Object.keys(obj)實現遍歷
Object.keys返回一個數組,該數組由對象自身的所有可枚舉屬性的鍵名組成。(只包含自身可枚舉的)(不含 Symbol 的,不含繼承的)
var obj = { 'name': "wen", 'age': '12', }; Object.keys(obj).forEach(function(item){ console.log(obj[item]); })
2.3、Object.getOwnPropertyNames(obj)
Object.getOwnPropertyNames返回一個數組,該對象由對象自身所有的屬性的鍵名組成。(包括自身所有的)(不含 Symbol 的,不含繼承的)
2.4、Reflect.ownKeys(obj)
Reflect.ownKeys返回一個數組,包含對象自身的所有鍵名,不管鍵名是 Symbol 或字符串,也不管是否可枚舉。(包含所有的除了繼承)
3、跳出循環:break、continue
3.1、break(結束整個循環操作)
for(var i=1;i<=10;i++) {
if(i==8) {
break;
}
console.log(i) //1234567
}
但是要注意,break語句跳出的是自己所在的那一層 for 循環語法,如果有多個 for 循環嵌套,break 總是跳出自己所在的那一層 for 循環。
for (let i=1; i<=10; i++) { for (let j=1; j<=10; j++) { if (j >= i) { break; } } // break 只是跳到這里,外層的for循環還在繼續 console.log('break'); }
3.2、continue(跳過本次循環,繼續執行下一個循環)
for(var i=1;i<=10;i++) {
if(i==8) {
continue;
}
console.log(i) //1234567910
}
3.3、return
return語句只能出現在函數體內,出現在代碼中的其他任何地方都會造成語法錯誤!return語句就是用于指定函數返回的值。
function a() { for(let i=0; i<10; i++){ console.log(i); if(i==3){ return 'aaa'; } } } console.log(a());
//報錯:Uncaught SyntaxError: Illegal return statement
for(var i=1;i<=10;i++) {
if(i==8) {
return;
}
console.log(i)
}

浙公網安備 33010602011771號