經過幾個事例,就能夠說明 for...of 循環在 JS 是不可或缺

做者:Dmitri Pavlutin
譯者:前端小智
來源:Dmitri Pavlutin

點贊再看,養成習慣javascript

本文 GitHub https://github.com/qq44924588... 上已經收錄,更多往期高贊文章的分類,也整理了不少個人文檔,和教程資料。歡迎Star和完善,你們面試能夠參照考點複習,但願咱們一塊兒有點東西。前端

clipboard.png

請教你們一個問題:什麼特性讓該編程語言更加優秀?java

我的看法:當該特性能夠組合多個其餘語言特性時。git

JavaScript 中的for...of語句就是這種狀況,可從ES2015開始使用。github

for...of能夠迭代數組,相似數組的對象以及一般全部可迭代的對象(mapset,DOM集合)。 面試

接下咱們經過事例來看看 for...of 一些有用的地方。編程

1. 數組的迭代

for...of的最多見應用是對數組項進行迭代。 該循環能夠很好且短暫地完成它,而無需其餘變量來保持索引。數組

例如:微信

const products = ['橘子', '蘋果']

for (const product of products.entries()) {
  console.log(product)
}
// "橘子"
// "蘋果"

for...of循環遍歷products,迭代的每項值分配給變量product數據結構

數組方法 entries() 能夠用於訪問迭代項的索引,該方法在每次迭代時返回一組鍵值對[index, item]

const products = ['橘子', '蘋果']

for (const [index, product] of products.entries()) {
  console.log(index, product)
}
// 0 "橘子"
// 1 "蘋果"

在每次迭代中,products.entries()返回一對索引和值,它們由const [index,product]表達式解構。

1.1 就地解構

首先,讓咱們看一下 for...of 循環的語法:

for (LeftHandSideExpression of Expression) {
  // statements
}

LeftHandSideExpression表達式能夠替換爲賦值表達式左側的任何內容。

在上面的例子中,LeftHandSideExpression是一個變量聲明 const products,也能夠是一個解構表達式 const [index, product]

接着,咱們遍歷一系列對象,提取每一個對象的屬性name

const persons = [
  { name: '前端小智' },
  { name: '王大冶' }
]

for (const { name } of persons) {
  console.log(name)
}

// 前端小智
// 王大冶

循環for (const { name } of persons) 遍歷person數組的對象,同時也就地解構( {name}) person對象的 name 屬性值。

你們都說簡歷沒項目寫,我就幫你們找了一個項目,還附贈【搭建教程】

2. 相似數組遍歷

for...of 除了能夠遍歷對象外,還能夠遍歷相似數組的對象。

arguments是函數體內的特殊變量,表示包含函數的全部參數,arguments 也是一個相似數組對象。例如:

function sum() {
  let sum = 0
  for (const number of arguments) {
    sum += number
  }

  return sum
}

sum(1, 2, 3) // 6

3.可迭代的簡要概述

JavaScript中的可迭代對象是什麼? 它是一個支持迭代協議的對象。

要檢查數據類型是否可迭代,能夠配合Symbol.iterator方法。 例如,下面的演示顯示了數組是可迭代的:

const array = [1, 2, 3]
const iterator = array[Symbol.iterator]()
iterator.next()  // {value: 1, done: false}

for...of接受可迭代,這很棒,由於這樣,咱們就能夠遍歷字符和數據結構(數組,類型化數組,集合,映射)等。

4. 字符串字符的遍歷

JavaScript 中的原始類型字符串是可迭代的。所以,咱們能夠輕鬆地遍歷字符串的字符。

const message = 'hello';

for (const character of message) {
  console.log(character);
}
// 'h'
// 'e'
// 'l'
// 'l'
// 'o'

message包含一個字符串值。 因爲message也是可迭代的,所以for...of循環遍歷message的字符。

5. Map 與 Set 迭代

Map是一個特殊的對象,它將一個鍵關聯到一個值。鍵能夠是任何基本類型(一般是字符串,但也能夠是數字等)

幸運的是,Map也是可迭代的(在鍵/值對上進行迭代),因此使用for...of能夠輕鬆地在全部鍵/值對上循環遍歷。

const names = new Map()
names.set(1, 'one')
names.set(2, 'two')

for (const [numbe, name] of names) {
  console.log(number, name)
}

// 1 "one"
// 2 "two"

for (const [number, name] of names)names 鍵/值對映射上進行迭代。

在每一個循環中,迭代器都會返回一個數組[key,value],並使用const [number,name]立即對這對數組進行解構。

一樣,以相同的方式能夠遍歷Set的項:

const colors = new Set(['white', 'blue', 'red', 'white']);

for (color of colors) {
  console.log(color);
}
// 'white'
// 'blue'
// 'red'

6. 遍歷普通 JavaScript 對象

遍歷普通 JS 對象的屬性/值對老是很痛苦的。

一般,我要先使用Object.keys()提取對象鍵,而後使用forEach()來遍歷鍵數組:

const person = {
  name: '前端小智',
  job: '前端分享者'
}

Object.keys(person).forEach(prop => {
  console.log(prop, person[prop])
})

// name 前端小智
// job 前端分享者

幸運的是,新的Object.entries() 函數與for...of組合提供了一個不錯的選擇:

const person = {
  name: '前端小智',
  job: '前端分享者'
}

for (const [prop, value] of Object.entries(person)) {
  console.log(prop, value)
}

// name 前端小智
// job 前端分享者

Object.entries(person)返回一個鍵和值元組數組:[['name', 'John Smith'], ['job', 'agent']]。 而後,對於for...of循環,遍歷元組,並將每一個元組解構const [prop,value]

7.遍歷 DOM 集合

你可能知道在 DOM 中使用HTMLCollection是多麼使人沮喪。由於HTMLCollection是一個相似數組的對象(而不是一個常規數組),因此咱們不能使用常規數組方法。

例如,每一個 DOM 元素的children屬性都是HTMLCollection。 所以,因爲for...of能夠在相似數組的對象上進行迭代,所以咱們能夠輕鬆地迭代子代:

const children = document.body.children;

for (const child of children) {
  console.log(child); // logs each child of <body>
}

此外,for...of能夠遍歷NodeList集合(可迭代)。 例如,函數document.querySelectorAll(query)返回一個NodeList

const allImages = document.querySelectorAll('img');

for (const image of allImages) {
  console.log(image); // log each image in the document
}

若是你想遍歷 DOM 中的不一樣種類的集合,那麼for...of語句是一個不錯的選擇。

8. 性能

在遍歷大數組時,for...of的速度可能比 for 要慢:

const a = [/* big array */];
for (let i = 0; i < a.length; i++) {
  console.log(a[i]);
}

在每次迭代中調用迭代器比經過增長索引訪問該項目的開銷更大。 可是,這種細微差異在使用大型陣列的應用程序中以及性能相當重要的應用程序中很是重要,這種狀況不多發生。


代碼部署後可能存在的BUG無法實時知道,過後爲了解決這些BUG,花了大量的時間進行log 調試,這邊順便給你們推薦一個好用的BUG監控工具 Fundebug

原文:https://dmitripavlutin.com/ja...

交流

文章每週持續更新,能夠微信搜索「 大遷世界 」第一時間閱讀和催更(比博客早一到兩篇喲),本文 GitHub https://github.com/qq449245884/xiaozhi 已經收錄,整理了不少個人文檔,歡迎Star和完善,你們面試能夠參照考點複習,另外關注公衆號,後臺回覆福利,便可看到福利,你懂的。

相關文章
相關標籤/搜索