javaScript數組之數組循環

Array,數組,是javaScript數據類型裏面的引用類型的數據,在咱們前端開發的過程當中,能夠說是使用的很是很是的頻繁,而對數組的循環也是咱們最多見的操做,今天給你們分享一下我本身在前端開發過程當中對數組循環操做使用的一些我的經驗和小技巧:前端

經常使用數組循環方法

  • for
  • for in
  • for of
  • forEach()
  • map()
  • some()
  • every()
  • filter()

for循環 `java

var arr = [{id: 1, color: 'red'}, {id: 2, color: 'orange'}, {id: 3, color: 'yellow'},
{id: 4, color: 'green'}, {id: 5, color: 'blue'} ];
for (var i = 0, len = arr.length; i < len; i++) {
    console.log(arr[i].color)    
}
// 輸出: 'red', 'orange', 'yellow', 'green', 'blue'
複製代碼

` 上面這個for循環應該是各位程序員使用的最最多的一個循環方式是吧,for循環是以聲明一個變量i,初始值爲0,只要i小於arr.length,i就加加一次,直到不小於爲止,則跳出循環。你們在看這段代碼的時候,是否有留意到,我把arr.length存儲到一個len的變量中,注意哦,這個是for循環使用的小技巧哦,由於在咱們循環遍歷數組的時候,若是沒有事先存儲,變量i在每次循環遞增以前便會反覆去計算數組的長度值,由於只要涉及到計算,確定就會消耗咱們的瀏覽器對js代碼解析的性能,而當咱們存儲起來,就優化了這個部分,這樣作對於咱們前端開發來講是很是有必要的呢,下面對for 循環作個總結:程序員

  • 一. 使用for循環時請把循環的對象的length存儲起來;
  • 二. for循環可使用break中斷循環;
  • 三. for循環不可使用return跳出循環;

for in循環 `es6

var arr = [{id: 1, color: 'red'}, {id: 2, color: 'orange'}, {id: 3, color: 'yellow'},
{id: 4, color: 'green'}, {id: 5, color: 'blue'} ];
for (var item in arr) {
    console.log(arr[item].color)    
}
// 輸出: 'red', 'orange', 'yellow', 'green', 'blue'
複製代碼

` 這樣看,彷佛以爲沒有什麼毛病,那麼在請看下面的代碼,仍然是上面這個數組數組

`瀏覽器

Array.prototype.test = '測試數組';
for (var item in arr) {
    console.log(arr[item].color)    
}
// 輸出: 'red', 'orange', 'yellow', 'green', 'blue', '測試數組'
複製代碼

` 你們是否是很驚奇的發現,竟然把咱們剛定義在原型鏈的test給輸出來了,這樣明顯不是咱們想要的,經過這一點其實就已經說明,for in不適合對數組循環操做,由於for in會把數組原型上的可枚舉屬性給遍歷出來,固然你能夠經過hasOwnProperty()方法來判斷性能優化

`數據結構

for (var item in arr) {
        if (arr.hasOwnProperty(item)) {
            console.log(arr[item].color) 
        }
    }
// 輸出: 'red', 'orange', 'yellow', 'green', 'blue'`
複製代碼

雖然你這樣作能夠,可是請明白一點,hasOwnProperty()方法是用來檢測當前項是否是實例自己的私有屬性的,for in循環始終都會去遍歷數組原型上的可枚舉對象,這樣對於js的性能優化來講是很是不利的。不只如此,for in的變量item,是字符數據類型,不能直接進行一些數學計算,即便你要操做,你也又會多寫一些代碼來處理,這樣就大大的增長了瀏覽器對js代碼解析的成本了。因此for in更可能是使用在object對象的循環上,for in總結下面幾點:函數

  • 一.for in循環不適用對數組的循環,由於for in會去遍歷原型上的全部可枚舉對象,對性能形成極大負擔;
  • 二.for in循環可使用break中斷循環,不可使用return返回語句;
  • 三.for in循環的變量item是是循環的key值,字符串數據類型;
  • 四.for in 適合循環object對象數據。

for of循環性能

for of是es6提出的一個新的循環方法,也是本次講解數組循環裏惟一介紹的一個es6的方法。for of 語句建立一個循環來迭代可迭代的對象。在 ES6 中引入的 for of 循環,以替代 for in 和 forEach() ,並支持新的迭代協議。for of 容許你遍歷 Arrays(數組), Strings(字符串), Maps(映射), Sets(集合)等可迭代的數據結構等。

`

Array.prototype.test = '測試數組';
var arr = [{id: 1, color: 'red'}, {id: 2, color: 'orange'}, {id: 3, color: 'yellow'},
{id: 4, color: 'green'}, {id: 5, color: 'blue'} ];
for (var item of arr) {
    console.log(item.color)    
}
// 輸出: 'red', 'orange', 'yellow', 'green', 'blue'

var str = 'ABCDEFG';
for (var cur of str) {
    console.log(cur)
}
// 輸出:A, B, C, D, E, F, G
複製代碼

` 看到這裏,咱們先拋開for of自己的工做機制,咱們先來瞅瞅它for in比有哪些不一樣與優點:

  • 一. for of能夠在循環的過程當中使用break中斷循環,可是你會說,for in也可使用breack中斷循環呀;
  • 二. for of不會去遍歷實例原型上的私有屬性,這點很重要哦;
  • 三. for of循環裏的變量item就是數組元素當前項自己;
  • 四. for of不適合遍歷object對象,若是非要使用,你須要結合Object.keys()來使用,否則確定會報錯*** is not iterable(不是可迭代的)。
  • 五. for of也不可使用return返回語句,若是不幸你使用了,確定會看到Illegal return statement(非法返回語句);

OK,咱們接下來簡單聊聊什麼是iterable,可迭代的數據對象,for of循環首先調用集合的Symbol.iterator方法,緊接着返回一個新的迭代器對象。迭代器對象能夠是任意具備.next()方法的對象;for of循環將重複調用這個方法,每次循環時調用一次。請看下面例子:

`

var iterable = {
  [Symbol.iterator]() {
    return {
      i: 0,
      next() {
        if (this.i < 3) {
          return { value: this.i++, done: false };
        }
        return { value: undefined, done: true };
      }
    };
  }
};

for (var value of iterable) {
  console.log(value);
}   //輸出 0, 1, 2
複製代碼

` 總結,for in更多適用object循環使用,for of更適用數組和類數組的使用。更多的for of循環的認識,能夠到MDN 去查看和學習。

forEach()循環

forEach()是javaScript數組裏的內置一個循環方法,在jQuery裏有一個相似的方法each(),本章節不會講jQuery裏的each()。forEach()接受一個回調函數,回調函數接受三個參數forEach(function(item, index, ary){}), item是數組元素當前項,index是當前項的索引值,ary是循環數組的自己,下面看代碼示例: `

var arr = [{id: 1, color: 'red'}, {id: 2, color: 'orange'}, {id: 3, color: 'yellow'},
{id: 4, color: 'green'}, {id: 5, color: 'blue'} ];
arr.forEach((item, index, ary) => {
    console.log(item.color);
    console.log(index);
    console.log(ary);
})
// 輸出: 'red', 'orange', 'yellow', 'green', 'blue';
// 輸出: 0, 1, 2, 3, 4
// 輸出: 5次:Array(5)
複製代碼

` forEach()循環的使用須要瞭解的特色就是:

  • 一.回調函數裏的三個參數,各自是誰;
  • 二.另外還有一點很是重要,也不能夠break中斷循環哦。若是你使用了break,確定會提示報錯:Illegal break statement(非法中斷語句)。
  • 三.forEach()不能夠return跳出循環,而你要是使用了return,則更坑,瀏覽器即不會提示報錯,它還會把循環執行完,你要是不瞭解這個特色,你會矇蔽的不知道咋回事。

map()循環

map()也是javaScript數組裏的內置方法,map()同forEach()同樣,接受一個回調函數,回調函數接受三個參數數map(function(item, index, ary){}), item是數組元素當前項,index是當前項的索引值,ary是循環數組的自己,下面看代碼示例: `

var arr = [{id: 1, color: 'red'}, {id: 2, color: 'orange'}, {id: 3, color: 'yellow'},
{id: 4, color: 'green'}, {id: 5, color: 'blue'} ];
arr.map((item, index, ary) => {
    console.log(item.color);
    console.log(index);
    console.log(ary);
})
// 輸出: 'red', 'orange', 'yellow', 'green', 'blue';
// 輸出: 0, 1, 2, 3, 4
// 輸出: 5次:Array(5)
複製代碼

` 這裏的輸出和forEach如出一轍,沒有任何差異,那麼問題來了,ECMAScript組織傻嗎,幹嗎發佈兩個如出一轍的方法呢,no,他們不傻,由於forEach()和map()確定有差異,看例子:

`

var ary = arr.map((item, index) => {
    return item.page
})
console.log(ary)
// 輸出新數組: ['red', 'orange', 'yellow', 'green', 'blue']
複製代碼

`

這個例子裏返回的這個新數組是不會影響原數組的,並且這個返回的機制,對於結合indexOf(),includes()數組查詢的操做很是有用。固然map也是不能夠在循環體裏使用break;所以map能夠總結兩點對它的認識:

  • 一.可使用return,return出來的是一個新數組,新數組不影響原數組;
  • 二.不可使用break。

some()循環

some()也是javaScript數組裏的內置方法,和前面的forEach,map同樣接收一個回調函數,回調函數裏默認三個參數,參數順序一樣是 item, index, arr(原數組);下面看例子: `

var arr = [{id: 1, color: 'red'}, {id: 2, color: 'orange'}, {id: 3, color: 'yellow'},
{id: 4, color: 'green'}, {id: 5, color: 'blue'} ];
arr.some(function(){
    console.log(arguments)
})  // 會輸出6次 Arguments(3)
arr.some(function(item, index){
    if (index == 4) {
        break;
    }
    console.log(item.color)
    }
)   // 不會輸出,會報錯Illegal break statement(非法中斷語句)

var bool1 = arr.some(function(item, index){
    console.log(item.color) //輸出 'red', 'orange', 'yellow', 'green', 'blue'
})  
console.log(bool1)   //輸出 fasle

var bool2 = arr.some(function(item, index){
    if (index == 4) {
        return true
    }
    console.log(item.color) //輸出 'red', 'orange', 'yellow', 'green'
})  
console.log(bool2)   //輸出 true

var bool3 = arr.some(function(item, index){
    if (index == 4) {
        return false
    }
    console.log(item.color) //輸出 'red', 'orange', 'yellow', 'green'
})  
console.log(bool3)   //輸出 false

var bool4 = arr.some(function(item, index){
    if (index == 4) {
        return ''   //這裏返回值只會返回布爾值,若是你給的返回值不是布爾值,則會給你轉換成布爾值
    }
    console.log(item.color) //輸出 'red', 'orange', 'yellow', 'green'
})  
console.log(bool4)   //輸出 false
複製代碼

` 經過上面的代碼演示,對some方法作以下總結:

  • 一.some方法接收一個回調函數,回調函數接收三個參數,item, index, arr(原數組)
  • 二.some方法不可使用break語句中斷循環;
  • 三.some方法可使用return語句跳出循環,some接收一個返回值,返回值是布爾值,默認false,return返回時能夠主動返回一個true或者false時的布爾,若是返回其餘數據類型會轉換成布爾值。

every()循環

every()也是javaScript數組裏的內置方法,是和上面的some方法很是相似的一個方法,就像是forEach與map的關係同樣,every與some很是類似,可是它們仍是有差異,下面看代碼: `

var arr = [{id: 1, color: 'red'}, {id: 2, color: 'orange'}, {id: 3, color: 'yellow'},
{id: 4, color: 'green'}, {id: 5, color: 'blue'} ];
arr.every(function(){
    console.log(arguments)
})  // 會輸出1次 Arguments(3)
arr.every(function(item, index){
    if (index == 4) {
        break;
    }
    console.log(item.color)
    }
)   // 不會輸出,會報錯Illegal break statement(非法中斷語句)
var bool1 = arr.every(function(item, index){
    console.log(item.color) //輸出 'red'
})  
console.log(bool1)   //輸出 fasle

var bool2 = arr.every(function(item, index){
    if (index == 4) {
        return true
    }
    console.log(item.color) //輸出 'red'
})  
console.log(bool2)   //輸出 false
複製代碼

` 到這裏,就已經能夠總結出every來了,說實話,我本身我的是十分不理解這個方法存在的意義,看下面幾點總結:

  • 一.every方法接收一個回調函數,回調函數接收三個參數,item, index, arr(原數組)
  • 二.every方法不可使用break語句中斷循環;
  • 三.every方法不能循環完整個數組,它只能遍歷到數組的第一個當前項,every一樣接收一個布爾的返回值,這個值就是固定的false。

filter()循環

filter()也是javaScript數組裏的內置方法,filter方法,語義上是過濾器,數組的過濾器,經過循環遍歷,而後根據條件來返回本身須要的數組當前項,filter是個使用很是頻繁的數組方法之一,下面咱們看代碼例子: `

var arr = [{id: 1, color: 'red'}, {id: 2, color: 'orange'}, {id: 3, color: 'yellow'},
{id: 4, color: 'green'}, {id: 5, color: 'blue'} ];
var ary = arr.filter(function(item, index){
    console.log(arguments)  // arguments包含三個默認參數,item,index,以及原數組
    console.log(item.color); //輸出'red', 'orange', 'yellow', 'green', 'blue'
    if (index > 1 && index < 4) {
        return item
    }
   
})
console.log(ary)    //輸出[ {id: 2, color: 'orange'}, {id: 3, color: 'yellow'},
{id: 4, color: 'green'}]
複製代碼

` 經過代碼演示,咱們發現filter和前面的全部數組方法同樣,接收一個回調函數,回調函數默認三個參數,filter能夠接收返回值,返回值默認以一個新數組接收,filter使用return不會跳出循環,下面咱們對filter作個總結:

  • 一. filter接收一個回調函數,回調函數默認三個參數,item, index, arr(原數組)
  • 二. filter接收一個返回值,返回值是個新數組,新數組不影響原數組,
  • 三. filter裏的return是返回知足本身條件的當前項的,不能夠跳出訓話,
  • 四. filter裏不可使用break中斷語句;

最後總結

在本次分享裏面,還有好幾個能夠循環數組的方式沒有介紹到,有es6標準裏的三個新方法keys()是對鍵名的遍歷、values()是對鍵值的遍歷,entries()是對鍵值對的遍歷,這個下次分享es6時在補充介紹了。而在本次的分享裏面,filter,some,every我我的認爲它們不是真正意義上的循環方法,它們都是爲了作特定需求數組處理的,只是它們在功能上面具有了對數組遍歷的能力。而咱們在對數組作循環處理的時候,我我的推薦使用for循環, for of循環,map(),forEach()這幾個爲主。本次分享就到這裏,謝謝!

相關文章
相關標籤/搜索