第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

全部開發(fā)者教程

ES6-10 入門教程

for…of

1. 前言

在編程中最常見的就是對數(shù)據(jù)的遍歷操作,ES5 有針對數(shù)組和對象的遍歷方法,但這些方法或多或少地都會(huì)存在一定的問題。為了統(tǒng)一解決這些問題,ES6 給出了終極的解決方案 ——for...of

for...of 對于可迭代的對象(包括:內(nèi)置的 String、Array、類似數(shù)組的對象(arguments 或 NodeList)、TypedArray、Map、Set,和用戶定義的可迭代對象等)上創(chuàng)建一個(gè)迭代循環(huán),它不局限于數(shù)組下的循環(huán),只要是可迭代的對象就可以被 for...of 進(jìn)行循環(huán)。

2. 基本語法

2.1 語法使用

for (const iterator of iterable) {
  // 執(zhí)行語句
}

參數(shù)解釋:

參數(shù) 描述
iterator 在每次迭代中,將不同屬性的值分配給變量,用于循環(huán)中語句的使用;
iterable 被迭代枚舉的對象。

2.2 迭代 Array

for...of 最常用的場景就是對數(shù)組的迭代,也是取代 for、forEach 的最好選擇。

let arr = [10, 20, 30];

for (let value of arr) {
    value += 1;
    console.log(value);
}
// 11
// 21
// 31

上面的代碼中對 value 值進(jìn)行加 1 操作,如果 value 值不能被修改,也可以使用 const 來定義 value。

2.3 迭代字符串

for...of 可以迭代字符串,迭代后的結(jié)果是把字符進(jìn)行分割,得到每個(gè)單個(gè)字符。

let str = '慕課';

for (let value of str) {
    console.log(value);
}
// 慕
// 課

2.4 迭代 TypedArray

let iterable = new Uint8Array([0x00, 0xff]);

for (let value of iterable) {
  console.log(value);
}
// 0
// 255

2.5 迭代 Set 和 Map

在 Set 和 Map 章節(jié)中我們就說到了,Set 和 Map 可以使用 for...of 來進(jìn)行循環(huán),主要因?yàn)?Set 和 Map 具有可迭代屬性。

let setArr = new Set([1, 1, 2, 2, 3, 3]);

for (let value of setArr) {
  console.log(value);
}
// 1
// 2
// 3

上面的代碼需要注意的是,迭代的是 new Set() 后的結(jié)果,new Set() 會(huì)對數(shù)組進(jìn)行去重操作,所以得到以上結(jié)果。

let map = new Map([["a", 1], ["b", 2], ["c", 3]]);

for (let value of map) {
  console.log(value);
}
// ["a", 1]
// ["b", 2]
// ["c", 3]

上面的代碼中使用 new Map() 傳入一個(gè)二維數(shù)組,這里需要注意的是,迭代的結(jié)果是一個(gè)帶有 key 和 value 的數(shù)組,所以也可以用數(shù)組解構(gòu)的方式 把 key 和 value 的值取出來,直接使用:

for (let [key, value] of map) {
  console.log(key, value);
}
// a 1
// b 2
// c 3

2.6 迭代類數(shù)組對象

1. 迭代 argument 對象

我們知道在函數(shù)中可以使用 Argument 對象拿到在調(diào)用函數(shù)時(shí)拿到傳遞的參數(shù),因?yàn)?arguments 不是一個(gè) Array,它屬于類數(shù)組,可以借助 call 來得到一個(gè)數(shù)組。[].slice.call(arguments), 而使用 for...of 可以直接對 arguments 循環(huán),得到的結(jié)果也只是傳入的參數(shù)。這個(gè)可以很方便地去循環(huán)類數(shù)組對象。

function argfn() {
  for (let argument of arguments) {
    console.log(argument);
  }
}
argfn(1,2,3)
// 1
// 2
// 3

上面的代碼可以看出來,打印的結(jié)果只有 1、2、3 沒有類數(shù)組上的其他屬性值。

2. 迭代 DOM 集合

其實(shí)最常見的數(shù)組對象是得到網(wǎng)頁上的 DOM 元素的集合,它也是一個(gè)類數(shù)組對象。比如一個(gè) NodeList 對象:下面的例子演示給每一個(gè) p 標(biāo)簽添加一個(gè) “read” 類。

//注意:這只能在實(shí)現(xiàn)了NodeList.prototype[Symbol.iterator]的平臺(tái)上運(yùn)行
let prags = document.querySelectorAll("p");

for (let value of prags) {
  value.classList.add("read");
}

上面的代碼,需要在在帶有 p 的標(biāo)簽的 html 文件中運(yùn)行。

3 知識(shí)對比

ES5 中提供了很多遍歷的方法,下面我們與之一一對比看看 for...of 有什么優(yōu)勢。

3.1 對比 for

最原始的語法是 for 循環(huán)語句,但是這種寫法比較麻煩,每個(gè)步驟的信息都需要手動(dòng)地去處理。

const fib = [1,1,2,3,5,8,13...];  // 斐波那切數(shù)列
for (let index = 0; index < fib.length; index++) {
  console.log(fib[index]);
}

3.2 對比 forEach

數(shù)組中內(nèi)置了 forEach 方法,這個(gè)方法的致命缺點(diǎn)就是不能跳出循環(huán),break 命令和 return 命令都不能奏效。

fib.forEach((value) => {
  console.log(value);
});

3.3 對比 for…in

  • for...in 用以遍歷對象的屬性,for...of 用以遍歷數(shù)據(jù),就像數(shù)組中的值一樣;
  • for...in 主要是針對對象循環(huán)而設(shè)計(jì)的,對于數(shù)組,鍵就是數(shù)字,但是在 for...in 循環(huán)中是以字符串作為鍵名;
  • for...in 循環(huán)不僅遍歷數(shù)字鍵名,還會(huì)遍歷手動(dòng)添加的其他鍵,甚至包括原型鏈上的鍵;
  • 某些情況下,for...in 循環(huán)以任意順序遍歷鍵名,主要是因?yàn)閷ο笤趦?nèi)存中的數(shù)據(jù)類型決定的。
for (let index in fib) {
  console.log(fib[index]);
}

3.4 for...of 的優(yōu)點(diǎn)

  • 有著同 for...in 一樣的簡潔語法,但是沒有 for...in 那些缺點(diǎn);
  • 不同于 forEach 方法,它可以與 break、continuereturn 配合使用;
  • 提供了遍歷所有數(shù)據(jù)結(jié)構(gòu)的統(tǒng)一操作接口。
for (let n of fib) {
  if (n > 520)
    break;
  console.log(n);
}

當(dāng)?shù)?xiàng)大于 520 時(shí) break 語句會(huì)跳出 for...of 循環(huán)。

4. 小結(jié)

  • 對于數(shù)組的處理盡量使用 for...of 去迭代數(shù)據(jù);
  • 如果要遍歷的是對象,并且沒有順序的限制可以使用 for...in 方式遍歷對象更好的處理數(shù)據(jù)。