国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

JavaScript 的 4 種數組遍歷方法: for VS forEach() VS for/in

joyqi / 800人閱讀

摘要:對于,除非使用箭頭函數,它的回調函數的將會變化。使用測試下面的代碼,結果如下打印打印要點使用的規(guī)則要求所有回調函數必須使用箭頭函數。

譯者按: JS 騷操作。

原文:For vs forEach() vs for/in vs for/of in JavaScript

譯者: Fundebug

本文采用意譯,版權歸原作者所有

我們有多種方法來遍歷 JavaScript 的數組或者對象,而它們之間的區(qū)別非常讓人疑惑。Airbnb 編碼風格禁止使用 for/in 與 for/of,你知道為什么嗎?

這篇文章將詳細介紹以下 4 種循環(huán)語法的區(qū)別:

for (let i = 0; i < arr.length; ++i)

arr.forEach((v, i) => { /* ... */ })

for (let i in arr)

for (const v of arr)

語法

使用forfor/in,我們可以訪問數組的下標,而不是實際的數組元素值:

for (let i = 0; i < arr.length; ++i) {
    console.log(arr[i]);
}

for (let i in arr) {
    console.log(arr[i]);
}

使用for/of,則可以直接訪問數組的元素值:

for (const v of arr) {
    console.log(v);
}

使用forEach(),則可以同時訪問數組的下標與元素值:

arr.forEach((v, i) => console.log(v));
非數字屬性

JavaScript 的數組就是 Object,這就意味著我們可以給數組添加字符串屬性:

const arr = ["a", "b", "c"];

typeof arr; // "object"

arr.test = "bad"; // 添加非數字屬性

arr.test; // "abc"
arr[1] === arr["1"]; // true, JavaScript數組只是特殊的Object

4 種循環(huán)語法,只有for/in不會忽略非數字屬性:

const arr = ["a", "b", "c"];
arr.test = "bad";

for (let i in arr) {
    console.log(arr[i]); // 打印"a, b, c, bad"
}

正因為如此,使用for/in遍歷數組并不好。

其他 3 種循環(huán)語法,都會忽略非數字屬性:

const arr = ["a", "b", "c"];
arr.test = "abc";

// 打印 "a, b, c"
for (let i = 0; i < arr.length; ++i) {
    console.log(arr[i]);
}

// 打印 "a, b, c"
arr.forEach((el, i) => console.log(i, el));

// 打印 "a, b, c"
for (const el of arr) {
    console.log(el);
}

要點: 避免使用for/in來遍歷數組,除非你真的要想要遍歷非數字屬性??梢允褂?ESLint 的guard-for-in規(guī)則來禁止使用for/in。

數組的空元素

JavaScript 數組可以有空元素。以下代碼語法是正確的,且數組長度為 3:

const arr = ["a", , "c"];

arr.length; // 3

讓人更加不解的一點是,循環(huán)語句處理["a",, "c"]["a", undefined, "c"]的方式并不相同。

對于["a",, "c"]for/inforEach會跳過空元素,而forfor/of則不會跳過。

// 打印"a, undefined, c"
for (let i = 0; i < arr.length; ++i) {
    console.log(arr[i]);
}

// 打印"a, c"
arr.forEach(v => console.log(v));

// 打印"a, c"
for (let i in arr) {
    console.log(arr[i]);
}

// 打印"a, undefined, c"
for (const v of arr) {
    console.log(v);
}

對于["a", undefined, "c"],4 種循環(huán)語法一致,打印的都是"a, undefined, c"。

還有一種添加空元素的方式:

// 等價于`["a", "b", "c",, "e"]`
const arr = ["a", "b", "c"];
arr[5] = "e";

還有一點,JSON 也不支持空元素:

JSON.parse("{"arr":["a","b","c"]}");
// { arr: [ "a", "b", "c" ] }

JSON.parse("{"arr":["a",null,"c"]}");
// { arr: [ "a", null, "c" ] }

JSON.parse("{"arr":["a",,"c"]}");
// SyntaxError: Unexpected token , in JSON at position 12

要點: for/inforEach會跳過空元素,數組中的空元素被稱為"holes"。如果你想避免這個問題,可以考慮禁用forEach:

parserOptions:
    ecmaVersion: 2018
rules:
    no-restricted-syntax:
        - error
        - selector: CallExpression[callee.property.name="forEach"]
          message: Do not use `forEach()`, use `for/of` instead
函數的 this

forfor/infor/of會保留外部作用域的this。

對于forEach, 除非使用箭頭函數,它的回調函數的 this 將會變化。

使用 Node v11.8.0 測試下面的代碼,結果如下:

"use strict";

const arr = ["a"];

arr.forEach(function() {
    console.log(this); // 打印undefined
});

arr.forEach(() => {
    console.log(this); // 打印{}
});

要點: 使用 ESLint 的no-arrow-callback規(guī)則要求所有回調函數必須使用箭頭函數。

Async/Await 與 Generators

還有一點,forEach()不能與 Async/Await 及 Generators 很好的"合作"。

不能在forEach回調函數中使用 await:

async function run() {
  const arr = ["a", "b", "c"];
  arr.forEach(el => {
    // SyntaxError
    await new Promise(resolve => setTimeout(resolve, 1000));
    console.log(el);
  });
}

不能在forEach回調函數中使用 yield:

function* run() {
  const arr = ["a", "b", "c"];
  arr.forEach(el => {
    // SyntaxError
    yield new Promise(resolve => setTimeout(resolve, 1000));
    console.log(el);
  });
}

對于for/of來說,則沒有這個問題:

async function asyncFn() {
    const arr = ["a", "b", "c"];
    for (const el of arr) {
        await new Promise(resolve => setTimeout(resolve, 1000));
        console.log(el);
    }
}

function* generatorFn() {
    const arr = ["a", "b", "c"];
    for (const el of arr) {
        yield new Promise(resolve => setTimeout(resolve, 1000));
        console.log(el);
    }
}

當然,你如果將forEach()的回調函數定義為 async 函數就不會報錯了,但是,如果你想讓forEach按照順序執(zhí)行,則會比較頭疼。

下面的代碼會按照從大到小打印 0-9:

async function print(n) {
    // 打印0之前等待1秒,打印1之前等待0.9秒
    await new Promise(resolve => setTimeout(() => resolve(), 1000 - n * 100));
    console.log(n);
}

async function test() {
    [0, 1, 2, 3, 4, 5, 6, 7, 8, 9].forEach(print);
}

test();

要點: 盡量不要在forEach中使用 aysnc/await 以及 generators。

結論

簡單地說,for/of是遍歷數組最可靠的方式,它比for循環(huán)簡潔,并且沒有for/inforEach()那么多奇怪的特例。for/of的缺點是我們取索引值不方便,而且不能這樣鏈式調用forEach(). forEach()

使用for/of獲取數組索引,可以這樣寫:

for (const [i, v] of arr.entries()) {
    console.log(i, v);
}
參考

For-each over an array in JavaScript?

Why is using “for…in” with array iteration a bad idea?

Array iteration and holes in JavaScript

關于Fundebug

Fundebug專注于JavaScript、微信小程序、微信小游戲、支付寶小程序、React Native、Node.js和Java線上應用實時BUG監(jiān)控。 自從2016年雙十一正式上線,Fundebug累計處理了10億+錯誤事件,付費客戶有Google、360、金山軟件、百姓網等眾多品牌企業(yè)。歡迎大家免費試用!

版權聲明

轉載時請注明作者Fundebug以及本文地址:
https://blog.fundebug.com/2019/03/11/4-ways-to-loop-array-inj-javascript/

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規(guī)行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/109102.html

相關文章

  • for...in VS. for...of

    摘要:在種和一樣都具有遍歷數組的功能,但是他們的返回結果并不相同,使用遍歷數組時,無法使用中斷循環(huán),也無法使用中斷,當然使用也不能返回到外層函數。枚舉對象循環(huán)不支持普通對象,如果想迭代一個對象的屬性,可以使用內建的方法使用方法獲取對象的數組 先看下面這兩種寫法:1. tabList.forEach((tab, i) => { if (tab.is_main) { th...

    Anchorer 評論0 收藏0
  • 一文徹底弄懂 for forEach for-in for-of 區(qū)別

    基本語法 下面列出了這幾個遍歷語法規(guī)則: for (let index = 0; index < array.length; index++) { const element = array[index] // ... } array.forEach(element => { // ... }) for (const key in array) { // ......

    newsning 評論0 收藏0
  • js--遍歷數組和對象方法及其效率--for-forof--foreach--forin

    摘要:數組優(yōu)化版優(yōu)化版谷歌版本正式版本位優(yōu)化版火狐版本優(yōu)化版結論這是一個尷尬的結論,谷歌火狐,同樣是最新版本或許谷歌才是王道,火狐跳舞吧,顫抖吧,你也太慢了吧,以谷歌為準相對來說作為新的遍歷方法具有可觀的效率對象 數組 var arr = new Array(10000000); var arr1 = []; var arr2 = []; var arr3 =...

    ThinkSNS 評論0 收藏0
  • .map() vs .forEach() vs for() 如何選擇?

    摘要:但是總是會被很多朋友說,這些人認為的速度要比快一點。如果你想用函數式編程寫個鏈式表達式來裝個逼,將會是你不二的選擇。來看下面這個例子鏈式風格接不起來,斷了最后根據上面的代碼,大家應該了解到跟的局限。 訪問原文地址 .map() vs .forEach() vs for() 筆者說,自己基本沒怎么用過for()來遍歷,主要是用.forEach()。 但是總是會被很多朋友說,這些人認為fo...

    iliyaku 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<