最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

JS中循環(huán)遍歷數組的幾種常用方式總結

 更新時間:2025年01月07日 10:52:40   作者:鐵錘妹妹i  
文章主要總結了?JS?中循環(huán)遍歷數組的十二種常用方式,包括?for?循環(huán)(普通和優(yōu)化版)、forEach、map、filter、for…of、for…in、find、findIndex、some、every、reduce?等,并對它們的特點、語法、優(yōu)缺點、適用場景及返回值等進行了詳細說明,需要的朋友可以參考下

第一種:for循環(huán),也是最常見的

最簡單的一種,也是使用頻率最高的一種,雖然性能不弱,但仍有優(yōu)化空間

const arr = [11, 22, 33, 44, 55, 66, 77, 88];
for (let i = 0; i < arr.length; i++) {
      console.log(arr[i]);
    }

打印結果:

第二種:優(yōu)化版for循環(huán)

const arr = [11, 22, 33, 44, 55, 66, 77, 88];
let len = arr.length
for (let i = 0; i < len; i++) {
      console.log(arr[i]);
    }

簡要說明:使用臨時變量,將長度緩存起來,避免重復計算數組長度,當數組較大時優(yōu)化效果才會比較明顯 缺點:不能在for循環(huán)中操作list的大小,比如除去或新加一個元素。 這種方法基本上是所有循環(huán)遍歷方法中性能最高的一種

第三種:forEach()

1.)forEach() 遍歷普通數組

const arr = [11, 22, 33, 44, 55, 66, 77, 88];
arr.forEach(item => {
      //forEach循環(huán)
      console.log(item);
    });

打印結果:

2.)forEach() 遍歷對象類型數組

const arrObj = [
      {
        id: 1,
        name: "張三",
        value: 10
      },
      {
        id: 2,
        name: "李四",
        value: 20
      },
      {
        id: 3,
        name: "王五",
        value: 30
      }
    ];
arrObj.forEach(item => {
   console.log(item.id + "-------" + item.name);
   item.value *= 10
});
console.log(arrObj)

打印結果: 

簡要說明: 數組自帶的foreach循環(huán),使用頻率較高,實際上性能比普通for循環(huán)弱。原因如下:

一般情況下,普通的 for 循環(huán)確實比 forEach 循環(huán)有更好的性能,這是因為 forEach 本質上是一個函數調用的過程,而函數調用會帶來額外的開銷。 具體來說,forEach 循環(huán)在每次迭代時都需要執(zhí)行一次回調函數,并且要對回調函數的執(zhí)行上下文進行綁定,這樣就需要創(chuàng)建和銷毀大量的函數堆棧,導致額外的系統(tǒng)開銷。而普通的 for 循環(huán)則不需要執(zhí)行函數調用操作,在每次迭代中直接訪問元素,極大地提高了代碼的執(zhí)行速度。

使用 forEach 時需要注意幾個點:

1)其實對于 forEach 方法,它本身是無法通過 break 或者 return 來中途停止循環(huán)的。forEach 方法會遍歷數組的每個元素,并對每個元素執(zhí)行提供的回調函數。無論回調函數中使用了 return 還是 break,都無法停止或跳出整個循環(huán)。 中斷方法:

  • 使用 try/catch 監(jiān)視代碼塊,在需要中斷的地方拋出異常。

  • 官方推薦方法(替換方法):用 everysome 代替 forEach 函數。every再碰到 return false 時候,終止循環(huán);some在碰到return true時候,終止循環(huán)。

  • forEach() 方法不會改變原數組。它只是對數組中的每個元素執(zhí)行提供的函數,而不會對數組本身進行修改或返回一個新的數組。
  • 如果在 forEach() 中對數組中的對象進行修改(比如改變對象的屬性),那么這些對象的內容會被改變,因為對象是引用類型。

3)forEach 中使用 await 異步代碼會導致 forEach 并不能保證按順序執(zhí)行??梢愿某墒褂胒or...of,因為for...of使用迭代器去遍歷,會按照迭代器對象定義的順序,從前往后依次遍歷。

針對第二點我們看下面的代碼示例:

const arr = [1, 2, 3];

arr.forEach(num => {
    console.log(num * 2); // 只是打印結果,不改變原數組
});

console.log(arr); // 輸出: [1, 2, 3]

// 對于對象的情況
const objArr = [{ value: 1 }, { value: 2 }];

objArr.forEach(item => {
    item.value *= 2; // 修改了對象的屬性
});

console.log(objArr); // 輸出: [{ value: 2 }, { value: 4 }]

針對第三點我們看下面的代碼示例:

async function test() {
	let arr = [4, 2, 1]
	arr.forEach(async item => {
		const res = await handle(item)
		console.log(res)
	})
	console.log('結束')
}

function handle(x) {
	return new Promise((resolve, reject) => {
		setTimeout(() => {
			resolve(x)
		}, 1000 * x)
	})
}

test()

我們期望的結果是:



1
結束

但實際上會輸出:

結束
1
2
4

具體原因

因為 forEach 底層實現(xiàn)是拿過來直接執(zhí)行了,這就導致它無法保證異步任務的執(zhí)行順序。比如后面的任務用時短,那么就又可能搶在前面的任務之前執(zhí)行。

解決方案 其實也很簡單, 我們利用for...of就能輕松解決。

async function test() {
  let arr = [4, 2, 1]
  for(const item of arr) {
	const res = await handle(item)
	console.log(res)
  }
	console.log('結束')
}

第四種:map()

定義和用法

1. map即是 “映射”的意思 ,原數組被“映射”成對應新數組 **2. map() 方法返回一個新數組,數組中的元素為原始數組元素調用函數處理后的值。

map() 不會改變原始數組。

map() 不會對空數組進行檢測。** 5. map支持return

 const arr = [11, 22, 33, 44, 55, 66, 77, 88];
 var newArr = arr.map((value, index) => {
      console.log(value + "----" + index);
      return value * 10;
    });
 console.log(newArr);

打印結果:

簡要說明: 這種方式也是用的比較廣泛的,雖然用起來比較優(yōu)雅,但實際效率還比不上foreach

forEach()和map()區(qū)別: 兩者都是用來遍歷數組的。

返回值:

forEach() 方法沒有返回值(或者說返回 undefined),它只是對數組的每個元素執(zhí)行指定的回調函數。

map() 方法返回一個新的數組,該數組包含對原數組每個元素執(zhí)行回調函數后的結果。

原數組的改變:

forEach() 方法不會改變原數組。它只是對數組中的每個元素執(zhí)行提供的函數,而不是對數組本身進行修改或返回一個新數組。但是,如果在forEach() 中對數組中的對象進行修改(比如改變對象的屬性),那么這些對象的內容會被改變,因為對象是引用類型。

map() 方法不會改變原數組,而是返回一個新的數組,該數組由原數組經過回調函數操作后的結果組成。

支持鏈式調用: foreach不支持鏈式調用,而map支持鏈式調用,可以繼續(xù)對返回的新數組進行操作。

 const array3 = [1, 2, 3, 4, 5];

 const doubledSum = array3
   .map((element) => element * 2)
   .reduce((accumulator, currentValue) => accumulator + currentValue, 0);
   
 console.log(doubledSum); // 輸出: 30

第五種:filter遍歷

定義和用法

filter用于對數組進行過濾。 filter() 方法創(chuàng)建一個新的數組,新數組中的元素是通過檢查指定數組中符合條件的所有元素。 filter() 不會對空數組進行檢測;不會改變原始數組

語法

array.filter(function(currentValue,index,arr), thisValue)

let arr = [56, 15, 48, 3, 7];

let newArr = arr.filter(function (value, index, array) {
    return value % 2 === 0;
});

console.log(newArr)
// [56, 48]

第六種:for....of 方法

作為ES6新增的循環(huán)方法,個人覺得相當好用,而且方便。這個方法避開了for-in循環(huán)的所有缺陷。而且,它可以正確響應break、continue和return語句。

//循環(huán)數組
let arr = ['123','qwewq','sfds'];
for(let item of arr){
    console.log(item);    //item指的的就是數組每一項的值。不是索引。
}
//輸出
//'123'
//'qwewq'
//'sfds'

for-of循環(huán)支持數組、字符串、Set、Map 等。但是for of也有一個致命傷,就像例子看到的,沒有索引。對,這是優(yōu)點也是缺點。遍歷數組對象,直接就是item.屬性(或者item[屬性]),而不用像for循環(huán)那樣arr[index].屬性(arrindex)。但是你有的時候真的就得用到index。不好意思,只能把數組轉成Map()。但我覺得真的需要用到index,還是換成forEach吧。

簡要說明: 這種方式是es6里面用到的,性能要好于forin,但仍然比不上普通for循環(huán)

第七種:for....in 方法

for in循環(huán)是用來遍歷對象的。要知道JavaScript對象的所有屬性都是字符串,不過屬性對應的值可以是任意數據類型。(注意:遍歷時不僅能讀取對象自身上面的成員屬性,也能遍歷出對象的原型屬性)

語法

let obj = {a:1, b:2, c:3};
for (let prop in obj) {    //prop指對象的屬性名
console.log(prop, obj[prop]);
}
// 輸出:
// a,1
// b,2
// c,3

for in同樣可以用來循環(huán)數組,但是不推薦這么做。由于Array也是對象,而它的每個元素的索引被視為對象的屬性,因此,for in循環(huán)可以直接循環(huán)出Array的索引,但得到的是String而不是Number,所以一旦你想用這個index去進行計算,就會出錯。而且因為會遍歷原型屬性,所以可能得出的結果不會是你想要的(具體細節(jié)不多說,需要了解的自己查詢,反正很多坑)。雖然可以用hasOwnProperty()方法避免這個缺陷,但是何必呢,循環(huán)方法那么多,換一個就是了。

for (var index in myArray) { // 不推薦這樣
console.log(myArray[index]);
}

為什么用for ... in?

簡要說明: 這個循環(huán)很多人愛用,但實際上,經分析測試,在眾多的循環(huán)遍歷方式中 它的效率是最低的

關于for ...of 和 for ...in 區(qū)別

for of 和 for in 是兩種不同的循環(huán)語句,用于遍歷可迭代對象枚舉對象的屬性,它們的區(qū)別如下:

1)遍歷的對象類型不同

  • for of 用于遍歷可迭代對象,如數組、字符串、Set、Map等;不會遍歷原型鏈。
  • for in 主要遍歷對象,不適用遍歷數組;會遍歷對象的整個原型鏈,性能差一些。

2)遍歷獲取的內容不同

  • for of 遍歷獲取的是對象的鍵值
  • for in 遍歷獲取的是對象的鍵名(屬性名)。

3)遍歷順序不同

  • for of 按照迭代器對象定義的順序,從前往后依次遍歷。
  • for in 遍歷對象屬性名時,順序不確定,可能是隨機的。(這也是不推薦用在數組上的原因之一)

4)可以使用的對象類型不同

  • for of 適用于可迭代對象,如數組、字符串、Set、Map等;
  • for in 適用于所有對象,包括普通對象、數組、字符串等。

注意:普通對象用 for of 遍歷會報錯。如果是類數組對象的話可以用Array.from() 轉成數組再遍歷。

  let forObject = Array.from({ 0: 'one', 1: 'two', 2: 'three', length: 3 })
  for (let item of forObject) {
    console.log(item, 'item')
  }

第八種:find方法

  • 遍歷數組,找到第一個符合條件的項,并返回該項;不會繼續(xù)遍歷數組;否則返回undefined
  • 不會改變數組
[1,4,-5,10].find((n) => n < 0 )
//-5

上面代碼找出數組中第一個小于0的成員

[1,5,10,15].find(function(value,index,arr){
 return value > 9
})
//10

上面代碼中,find方法的回調函數可以接受三個參數,依次為當前的值、當前的位置和原數組。

第九種:findIndex方法

  • 遍歷數組找到第一個符合條件的項,并返回該項的索引值;不會繼續(xù)遍歷數組;否則返回-1。
  • 不會改變數組
[1,5,10,15].findIndex(function(value,index,arr){
 return value > 9
})
//2

findIndex() 當中的回調函數也是接收三個參數,與find() 相同。 

第十種:Array.some() 方法

1)如果有一個元素滿足條件,則表達式返回true,剩余的元素不會再執(zhí)行檢測。 2)如果沒有滿足條件的元素,則返回false。 3)返回值是布爾值

注意:

1) some() 不會對空數組進行檢測。 2) some() 不會改變原始數組。

 var ages = [3, 18, 17, 16]
 var checkoutVal = function checkout (age) {
   console.log(age >= 18) // false true  有一個滿足條件的會停止檢測剩余的元素
   return age >= 18
 }
 console.log(ages.some(checkoutVal)) // true
let someArr = [2,3,4];
let someResult = someArr.some((item, index)=>{
  return item > 3
});
console.log(someResult);
// 結果為: true

第十一種:Array.every() 方法 (所有的,每一個)

1)如果數組中有一個元素不滿足,則整個表達式返回false;且剩余的元素不會再進行檢測 2)如果所有元素都滿足條件,則返回true。 3)返回值是布爾值

注意:

1) every() 不會對空數組進行檢測。 2) every() 不會改變原始數組。

  var ages = [3, 18, 17, 16]
  const fn = (currentValue) => currentValue < 40
  console.log(ages.every(fn)) // true  值全都符合函數條件
let everyArr = [2,3,4];
let everyResult = everyArr.every((item, index)=>{
  return item > 0
});
console.log(everyResult);
// 結果為: true

Array.some() 和Array.every() 的區(qū)別???

第十二種:reduce() 方法

reduce() 方法接受一個回調函數和一個可選的初始值作為參數,對數組中的每個元素依次調用回調函數,并將上一次調用的結果傳遞給下一次調用,最終返回一個累積的結果。

array.reduce(callback, initialValue)
  • 其中,callback 是一個函數,它可以接受四個參數:accumulator(累加器)、currentValue(當前值)、currentIndex(當前索引)和 array(當前數組)。 initialValue 是可選的初始值,
  • 如果提供了初始值,則作為第一次調用回調函數時的 accumulator 值;
  • 如果沒有提供初始值,則使用數組的第一個元素作為初始值,并從第二個元素開始調用回調函數。

使用案例:

// reducer
let reduceArr = [0,1,2,3,4]
let reduceResult = reduceArr.reduce((a, b)=>{
  return a + b;
});
console.log(reduceResult);
// 結果: 10

上述列舉了幾種方式都有一一做過對比分析,基本上可以得出的結論是: 普通for循環(huán)才是最優(yōu)雅的,優(yōu)化后的for循環(huán)最快

注意: 數組方法無法中途停止循環(huán),所以都不可以使用break和continue; for循環(huán)之類的不可以return,但是能正常使用break和continue;

以上就是JS中循環(huán)遍歷數組的幾種常用方式總結的詳細內容,更多關于JS循環(huán)遍歷數組的資料請關注腳本之家其它相關文章!

相關文章

  • 使用canvas實現(xiàn)仿新浪微博頭像截取上傳功能

    使用canvas實現(xiàn)仿新浪微博頭像截取上傳功能

    用戶提供圖像大小尺寸不合適,如何用截取上傳呢?接下來小編教大家使用使用canvas實現(xiàn)仿新浪微博頭像截取上傳功能解決問題,需要的朋友一起學習吧。
    2015-09-09
  • JS函數的返回值如何使用

    JS函數的返回值如何使用

    函數是一塊js代碼塊,被定義一次但可以執(zhí)行和調用多次,js中的函數也是對象可以像其他對象那樣操作和執(zhí)行,js函數也被稱為函數對象,本文給大家介紹JS函數的返回值如何使用,感興趣的朋友跟隨小編一起看看吧
    2024-02-02
  • Textarea與懶惰渲染實現(xiàn)代碼

    Textarea與懶惰渲染實現(xiàn)代碼

    2008年有啊第一次性能優(yōu)化時,我們曾用textarea來存貯需要懶惰渲染的節(jié)點
    2012-01-01
  • JavaScript計時器示例分析

    JavaScript計時器示例分析

    這篇文章主要介紹了JavaScript計時器示例分析,需要的朋友可以參考下
    2015-02-02
  • js有序數組的連接問題

    js有序數組的連接問題

    昨天碰到一道關于如何解決有序數組的連接問題,這是一個很常見的問題。但是這里要考慮到代碼的效率問題,因為要連接的數組都是有序的,這是一個非常重要的前提條件
    2013-10-10
  • 微信小程序教程系列之視圖層的條件渲染(10)

    微信小程序教程系列之視圖層的條件渲染(10)

    這篇文章主要為大家詳細介紹了微信小程序教程系列之視圖層的條件渲染,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-04-04
  • js實現(xiàn)時分秒倒計時

    js實現(xiàn)時分秒倒計時

    這篇文章主要為大家詳細介紹了js實現(xiàn)時分秒倒計時,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-12-12
  • 漂亮! js實現(xiàn)顏色漸變效果

    漂亮! js實現(xiàn)顏色漸變效果

    很神奇!js實現(xiàn)顏色漸變效果,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-08-08
  • 微信小程序實現(xiàn)漸入漸出動畫效果

    微信小程序實現(xiàn)漸入漸出動畫效果

    這篇文章主要給大家介紹了關于微信小程序實現(xiàn)漸入漸出動畫效果的相關資料,文中通過示例代碼介紹的非常詳細,對大家學習或者使用微信小程序具有一定的參考學習價值,需要的朋友們下面來一起學習學習吧
    2019-06-06
  • uniApp常見面試題及答案(推薦!)

    uniApp常見面試題及答案(推薦!)

    uni-app是一個使用Vue.js開發(fā)所有前端應用的框架,下面這篇文章主要給大家介紹了關于uniApp常見面試題及答案的相關資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下
    2023-02-02

最新評論

葫芦岛市| 勐海县| 镶黄旗| 大丰市| 玉溪市| 梁山县| 社会| 通州市| 中超| 句容市| 镇雄县| 景宁| 宜兴市| 武定县| 吕梁市| 武城县| 志丹县| 彩票| 西盟| 清水河县| 江油市| 八宿县| 德格县| 昌吉市| 镇赉县| 通州区| 比如县| 廉江市| 新泰市| 融水| 兴安盟| 托克逊县| 乌兰察布市| 台湾省| 营山县| 上虞市| 邢台县| 许昌县| 潞西市| 崇仁县| 霍城县|