細說JS循環方法

楔子

傳統的JS循環方法,while,do while,for與其餘語言相似,本文不作過多描述,更多的集中在:數組

  • 常見遍歷方法for-in、for-of、entires、Object.keys、Object.getOwnProperty比較。
  • 數組遍歷map、forEach、reduce、every、some、fiter方法的比較。

常見遍歷方法

  • for-in:遍歷數組索引、對象的屬性,用於遍歷可枚舉屬性,包括自有屬性、繼承自原型的屬性

var obj = {"name":"sme","sex":"female"};
Object.defineProperty(obj, "age", {value:"18", enumerable:false});//增長不可枚舉的屬性age
Object.prototype.protoPer1 = function(){console.log("name is sme");};//經過原型鏈增長屬性,爲一個函數
for(var a in obj){
    console.log(a);
}
// 輸出:name,sex,ProtoPer1
//注意:屬性age爲不可可枚舉,因此沒有輸出。
複製代碼
  • for-of:容許遍歷 Arrays(數組), Strings(字符串), Maps(映射), Sets(集合),Arguments Object(參數對象)等可迭代的數據結構,返回的是屬性值,但不容許遍歷對象

for (const value of strings) { 
  console.log(value);
}
複製代碼
  • forEach:遍歷數組,調用數組的每一個元素,並將元素傳遞給回調函數。

    不能使用break、continue和return語句 可改變原有數組
var arr = [1,2,3];
arr.forEach(
    function(value,index,arr){
        console.log(index)//索引
        console.log(value)//值
        //如下爲錯誤代碼
        //if(index/2 === 0){
           // continue;
        //}
    },this)
複製代碼
  • for-in和for-of和forEach比較

  1. for..of:適用遍歷數/數組對象/字符串/map/set等擁有迭代器對象的集合.可是不能遍歷對象,由於沒有迭代器對象.
  2. 與forEach()不一樣的是,它能夠正確響應break、continue和return語句
  3. for-of循環不支持普通對象,但若是你想迭代一個對象的屬性,你能夠用for-in循環或內建的Object.keys()方法。
  • Object.getOwnProperty:主要用於返回對象的自有屬性,包括可枚舉和不可枚舉的屬性,不包括繼承自原型的屬性。

var obj = {"name":"sme","sex":"female"};
Object.defineProperty(obj, "age", {value:"18", enumerable:false});//增長不可枚舉的屬性age
Object.prototype.protoPer1 = function(){console.log("name is sme");};//經過原型鏈增長屬性,爲一個函數
console.log(Object.getOwnPropertyNames(obj));
//輸出:[name,sex,age]
//注意:返回的也是數組,原型上添加的屬性不會被遍歷到
複製代碼
  • Object.keys: 返回一個數組,元素均爲對象自有可枚舉的屬性

var obj = {"name":"sme","sex":"female"};
Object.defineProperty(obj, "age", {value:"18", enumerable:false});//增長不可枚舉的屬性age
Object.prototype.protoPer1 = function(){console.log("name is sme");};//經過原型鏈增長屬性,爲一個函數
console.log(Object.keys(obj));
//輸出:[name,sex]
//注意:原型上添加的屬性不會被遍歷到
複製代碼
  • Object.entries:返回二元數組,鍵值對

同上例子
console.log(Object.entries(obj))
\\輸出[["name","sme"],["sex","female"]]
複製代碼
  • array.map(): 遍歷數組,與forEach類,區別是不改變原數組,可使用return返回結果,break,contiune不生效

var arr = [1,2,3]
var res = arr.map(function(val,index,arr){
    return val*2
})
//res=[2,4,6]
//arr=[1,2,3]
複製代碼
  • array.filter():遍歷過濾數組
  • every():遍歷數組是否所有知足,返回true
array.every(function(currentValue,index,arr), thisValue)
複製代碼
  • some(): 遍歷數組一個知足即爲true
array.some(function(currentValue,index,arr),thisValue)
複製代碼
  • array.reduce(function(total, currentValue, currentIndex, arr)):

    接收一個函數做爲累加器,數組中的每一個值(從左到右)開始縮減,最終計算爲一個值。
var numbers = [65, 44, 12, 4];
function getSum(total, num) {
    return total + num;
}
function myFunction(item) {
    document.getElementById("demo").innerHTML = numbers.reduce(getSum);
}
//輸出:125
複製代碼

總結

  1. forEach、map、filter、reduce、every、some 都會有 break 和 continue不生效的問題,由於是在function中,但function解決了閉包陷阱的問題; 要使用 break、continue 可使用 for、for-in、for-of、while。
  2. for-of爲ES6語法糖,儘可能使用for-of;
  3. 用於循環對象屬性使用:for-in
相關文章
相關標籤/搜索