亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

你不知道的forEach函數(shù)解析

 更新時(shí)間:2023年05月18日 14:24:54   作者:碼的是生活  
這篇文章主要介紹了你不知道的forEach函數(shù)的相關(guān)資料,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下

老實(shí)說(shuō)我不喜歡用forEach,因?yàn)樗鼘?dǎo)致的一些bug總是這么不經(jīng)意,盤(pán)點(diǎn)我不喜歡的原因

原因一:不支持處理異步函數(shù)

先看一個(gè)例子:

async function test() {
    let arr = [3, 2, 1]
    arr.forEach(async item => {
        const res = await mockSync(item)
        console.log(res)
    })
    console.log('end')
}
function mockSync(x) {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
                resolve(x)
        }, 1000 * x)
    })
}
test()
我們期望的結(jié)果是:
3
2 
1
end
但是實(shí)際上會(huì)輸出:
end
1
2
3

JavaScript中的forEach()方法是一個(gè)同步方法,它不支持處理異步函數(shù)。如果你在forEach中執(zhí)行了異步函數(shù),forEach()無(wú)法等待異步函數(shù)完成,它會(huì)繼續(xù)執(zhí)行下一項(xiàng)。這意味著如果在forEach()中使用異步函數(shù),無(wú)法保證異步任務(wù)的執(zhí)行順序。

替代forEach的方式

1.方式一

可以使用例如map()、filter()reduce()等,它們支持在函數(shù)中返回Promise,并且會(huì)等待所有Promise完成。

使用map()Promise.all()來(lái)處理異步函數(shù)的示例代碼如下:

const arr = [1, 2, 3, 4, 5];
async function asyncFunction(num) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve(num * 2);
    }, 1000);
  });
}
const promises = arr.map(async (num) => {
  const result = await asyncFunction(num);
  return result;
});
Promise.all(promises).then((results) => {
  console.log(results); // [2, 4, 6, 8, 10]
});

由于我們?cè)诋惒胶瘮?shù)中使用了await關(guān)鍵字,map()方法會(huì)等待異步函數(shù)完成并返回結(jié)果,因此我們可以正確地處理異步函數(shù)。

方式二 使用for循環(huán)來(lái)處理異步函數(shù)

const arr = [1, 2, 3, 4, 5];
async function asyncFunction(num) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve(num * 2);
    }, 1000);
  });
}
async function processArray() {
  const results = [];
  for (let i = 0; i < arr.length; i++) {
    const result = await asyncFunction(arr[i]);
    results.push(result);
  }
  console.log(results); // [2, 4, 6, 8, 10]
}
processArray();

原因二:無(wú)法捕獲異步函數(shù)中的錯(cuò)誤

如果異步函數(shù)在執(zhí)行時(shí)拋出錯(cuò)誤,forEach()無(wú)法捕獲該錯(cuò)誤。這意味著即使在異步函數(shù)中出現(xiàn)錯(cuò)誤,forEach()仍會(huì)繼續(xù)執(zhí)行。

原因三:除了拋出異常以外,沒(méi)有辦法中止或跳出 forEach() 循環(huán)

forEach()方法不支持使用breakcontinue語(yǔ)句來(lái)跳出循環(huán)或跳過(guò)某一項(xiàng)。如果需要跳出循環(huán)或跳過(guò)某一項(xiàng),應(yīng)該使用for循環(huán)或其他支持breakcontinue語(yǔ)句的方法。

原因四:forEach 刪除自身元素,index不可被重置

forEach中我們無(wú)法控制 index 的值,它只會(huì)無(wú)腦的自增直至大于數(shù)組的 length 跳出循環(huán)。所以也無(wú)法刪除自身進(jìn)行index重置,先看一個(gè)簡(jiǎn)單例子:

let arr = [1,2,3,4]
arr.forEach((item, index) => {
    console.log(item); // 1 2 3 4
    index++;
});

原因五:this指向問(wèn)題

forEach()方法中,this關(guān)鍵字引用的是調(diào)用該方法的對(duì)象。但是,在使用普通函數(shù)或箭頭函數(shù)作為參數(shù)時(shí),this關(guān)鍵字的作用域可能會(huì)出現(xiàn)問(wèn)題。在箭頭函數(shù)中,this關(guān)鍵字引用的是定義該函數(shù)時(shí)所在的對(duì)象。在普通函數(shù)中,this關(guān)鍵字引用的是調(diào)用該函數(shù)的對(duì)象。如果需要確保this關(guān)鍵字的作用域正確,可以使用bind()方法來(lái)綁定函數(shù)的作用域。以下是一個(gè)關(guān)于forEach()方法中this關(guān)鍵字作用域問(wèn)題的例子:

const obj = {
  name: "Alice",
  friends: ["Bob", "Charlie", "Dave"],
  printFriends: function () {
    this.friends.forEach(function (friend) {
      console.log(this.name + " is friends with " + friend);
    });
  },
};
obj.printFriends();

在這個(gè)例子中,我們定義了一個(gè)名為obj的對(duì)象,它有一個(gè)printFriends()方法。在printFriends()方法中,我們使用forEach()方法遍歷friends數(shù)組,并使用普通函數(shù)打印每個(gè)朋友的名字和obj對(duì)象的name屬性。但是,當(dāng)我們運(yùn)行這個(gè)代碼時(shí),會(huì)發(fā)現(xiàn)輸出結(jié)果為:

undefined is friends with Bob
undefined is friends with Charlie
undefined is friends with Dave

這是因?yàn)?,?code>forEach()方法中使用普通函數(shù)時(shí),該函數(shù)的作用域并不是調(diào)用printFriends()方法的對(duì)象,而是全局作用域。因此,在該函數(shù)中無(wú)法訪問(wèn)obj對(duì)象的屬性。

為了解決這個(gè)問(wèn)題,可以使用bind()方法來(lái)綁定函數(shù)的作用域,或使用箭頭函數(shù)來(lái)定義回調(diào)函數(shù)。以下是使用bind()方法解決問(wèn)題的代碼示例:

const obj = {
  name: "Alice",
  friends: ["Bob", "Charlie", "Dave"],
  printFriends: function () {
    this.friends.forEach(
      function (friend) {
        console.log(this.name + " is friends with " + friend);
      }.bind(this) // 使用bind()方法綁定函數(shù)的作用域
    );
  },
};
obj.printFriends();

在這個(gè)例子中,我們使用bind()方法來(lái)綁定函數(shù)的作用域,將該函數(shù)的作用域綁定到obj對(duì)象上。運(yùn)行代碼后,輸出結(jié)果為:

Alice is friends with Bob 
Alice is friends with Charlie 
Alice is friends with Dave

通過(guò)使用bind()方法來(lái)綁定函數(shù)的作用域,我們可以正確地訪問(wèn)obj對(duì)象的屬性。

另一種解決方法是使用箭頭函數(shù)。由于箭頭函數(shù)沒(méi)有自己的this,它會(huì)繼承它所在作用域的this。因此,在箭頭函數(shù)中,this關(guān)鍵字引用的是定義該函數(shù)時(shí)所在的對(duì)象。代碼略

原因六: forEach性能比f(wàn)or循環(huán)低

for:for循環(huán)沒(méi)有額外的函數(shù)調(diào)用棧和上下文,所以它的實(shí)現(xiàn)最為簡(jiǎn)單。
forEach:對(duì)于forEach來(lái)說(shuō),它的函數(shù)簽名中包含了參數(shù)和上下文,所以性能會(huì)低于 for 循環(huán)。

原因七:會(huì)跳過(guò)已刪除或者未初始化的項(xiàng)

// 跳過(guò)未初始化的值
const array = [1, 2, /* empty */, 4];
let num = 0;
array.forEach((ele) => {
  console.log(ele);
  num++;
});
console.log("num:",num);
//  1
//  2 
//  4 
// num: 3
// 跳過(guò)已刪除的值
const words = ['one', 'two', 'three', 'four'];
words.forEach((word) => {
  console.log(word);
  if (word === 'two') {
  // 當(dāng)?shù)竭_(dá)包含值?`two`?的項(xiàng)時(shí),整個(gè)數(shù)組的第一個(gè)項(xiàng)被移除了
  // 這導(dǎo)致所有剩下的項(xiàng)上移一個(gè)位置。因?yàn)樵?`four`?正位于在數(shù)組更前的位置,所以?`three`?會(huì)被跳過(guò)。
    words.shift(); //'one' 將從數(shù)組中刪除
  }
}); // one // two // four
console.log(words); // ['two', 'three', 'four']

原因八:forEach使用不會(huì)改變?cè)瓟?shù)組

forEach() 被調(diào)用時(shí),不會(huì)改變?cè)瓟?shù)組,也就是調(diào)用它的數(shù)組。但是那個(gè)對(duì)象可能會(huì)被傳入的回調(diào)函數(shù)改變

// 例子一
const array = [1, 2, 3, 4]; 
array.forEach(ele => { ele = ele * 3 }) 
console.log(array); // [1,2,3,4]
// 解決方式,改變?cè)瓟?shù)組
const numArr = [33,4,55];
numArr.forEach((ele, index, arr) => {
    if (ele === 33) {
        arr[index] = 999
    }
})
console.log(numArr);  // [999, 4, 55]
// 例子二
const changeItemArr = [{
    name: 'wxw',
    age: 22
}, {
    name: 'wxw2',
    age: 33
}]
changeItemArr.forEach(ele => {
    if (ele.name === 'wxw2') {
        ele = {
            name: 'change',
            age: 77
        }
    }
})
console.log(changeItemArr); // [{name: "wxw", age: 22},{name: "wxw2", age: 33}]
// 解決方式
const allChangeArr = [{    name: 'wxw',    age: 22}, {    name: 'wxw2',    age: 33}]
allChangeArr.forEach((ele, index, arr) => {
    if (ele.name === 'wxw2') {
        arr[index] = {
            name: 'change',
            age: 77
        }
    }
})
console.log(allChangeArr); // // [{name: "wxw", age: 22},{name: "change", age: 77}]

好了,我還是使用for...of去替代forEach

到此這篇關(guān)于你不知道的forEach函數(shù)的文章就介紹到這了,更多相關(guān)js forEach函數(shù)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論