深入瞭解JS中的for...of迴圈

2020-10-12 18:00:33
本篇文章帶大家深入瞭解一下JavaScript中的for...of迴圈。有一定的參考價值,有需要的朋友可以參考一下,希望對你有所幫助。

for...of語句建立的迴圈可以遍歷物件。在ES6中引入的for...of可以替代另外兩種迴圈語句for...in和forEach(),而且這個新的迴圈語句支援新的迭代協定。for...of允許你遍歷可迭代的資料結構,比如陣列、字串、對映、集合等。

語法

for (variable of iterable) {
    statement
}
  • variable:每個迭代的屬性值被分配給variable

  • iterable:一個具有可列舉屬性並且可以迭代的物件

我們使用一些範例來闡述。

Arrays

array是簡單的列表,看上去像object。陣列原型有多種方法,允許在其上執行操作,比如遍歷。下面的範例使用for...of來對一個array進行遍歷操作:

const iterable = ['mini', 'mani', 'mo'];

for (const value of iterable) {
    console.log(value);
}

// Output:
// => mini
// => mani
// => mo

其結果就是列印出iterable陣列中的每一個值。

Map

Map物件持有key-value對。物件和原始值可以當作一個keyvalueMap物件根據插入的方式遍歷元素。換句話說,for...of在每次迭代中返回一個kay-value對的陣列。

const iterable = new Map([['one', 1], ['two', 2]]);

for (const [key, value] of iterable) {
    console.log(`Key: ${key} and Value: ${value}`);
}

// Output:
// => Key: one and Value: 1
// => Key: two and Value: 2

Set

Set物件允許你儲存任何型別的唯一值,這些值可以是原始值或物件。Set物件只是值的集合。Set元素的迭代是基於插入順序,每個值只能發生一次。如果你建立一個具有相同元素不止一次的Set,那麼它仍然被認為是單個元素。

const iterable = new Set([1, 1, 2, 2, 1]);

for (const value of iterable) {
    console.log(value);
}

// Output:
// => 1
// => 2

儘管我們建立的Set有多個12,但遍歷輸出的只有12

String

字串用於以文字形式儲存資料。

const iterable = 'javascript';

for (const value of iterable) {
    console.log(value);
}

// Output:
// => "j"
// => "a"
// => "v"
// => "a"
// => "s"
// => "c"
// => "r"
// => "i"
// => "p"
// => "t"

在這裡,對字串執行迭代,並列印出每個索引上(index)的字元。

Arguments Object

把一個引數物件看作是一個類似陣列的物件,與傳遞給函數的引數相對應。這是一個用例:

function args() {
    for (const arg of arguments) {
        console.log(arg);
    }
}

args('a', 'b', 'c');

// Output:
// => a
// => b
// => c

你可能在想,到底發生了什麼?正如我前面說過的,當呼叫函數時,引數會接收傳入args()函數的任何引數。因此,如果我們將20個引數傳遞給args()函數,我們將輸出20個引數。

在上面的範例基礎上做一些調整,比如給args()函數,傳入一個物件、陣列和函數:

function fn(){
return 'functions';
}

args('a', 'w3cplus', 'c',{'name': 'airen'},['a',1,3],fn());

// Output:
// => "a"
// => "w3cplus"
// => "c"
// => Object {
// =>     "name": "airen"
// => }
// => Array [
// =>    "a",
// =>    1,
// =>    3
// => ]
// => "functions"

Generators

生成器是一個函數,它可以退出函數,稍後重新進入函數。

function* generator(){ 
    yield 1; 
    yield 2; 
    yield 3; 
};

for (const g of generator()) { 
    console.log(g); 
}

// Output:
// => 1
// => 2
// => 3

function* 定義一個生成器函數,該函數返回生成器物件。更多關於生成器相關的資訊,可以點選這裡

關閉迭代器

JavaScript中提供了四種已知的終止迴圈的方法:breakcontinuereturnthrow。來看一個範例:

const iterable = ['mini', 'mani', 'mo'];

for (const value of iterable) {
console.log(value);
break;
}

// Output:
// => mini

在這個例子中,我們使用break關鍵詞來終止一個迴圈,並且只列印出一個mini

普通物件不可迭代

for...of迴圈只能和迭代一起工作。但普通物件是不可迭代的。讓我們看看:

const obj = { fname: 'foo', lname: 'bar' };

for (const value of obj) { // TypeError: obj[Symbol.iterator] is not a function
    console.log(value);
}

在這裡,我們定義了一個普通物件obj,當我們嘗試for...ofobj進行操作時,會報錯:TypeError: obj[Symbol.iterator] is not a function

我們可以把一個類似陣列的物件轉找成一個陣列。物件將具有length屬性,它的元素可以被索引。來看一個範例:

const obj = { length: 3, 0: 'foo', 1: 'bar', 2: 'baz' };
const array = Array.from(obj);
for (const value of array) { 
    console.log(value);
}
// Output:
// => foo
// => bar
// => baz

Array.from()方法從類似陣列(Array-lik)或迭代物件中建立了一個新的陣列範例。

for...of vs. for...in

for...in在迴圈中將遍歷物件中所有可列舉屬性。

Array.prototype.newArr = () => {};
Array.prototype.anotherNewArr = () => {};
const array = ['foo', 'bar', 'baz'];
for (const value in array) { 
    console.log(value);
}
// Outcome:
// => 0
// => 1
// => 2
// => newArr
// => anotherNewArr

for...in不僅可以列舉陣列裡宣告的值,它還可以從建構函式的原型中尋找繼承的非列舉屬性,比如上例中的newArranotherNewArr,並將它們列印出來。

for...of可以對陣列和物件等做更具體的操作,但並不表示包括所有物件。

注意:任何具有Symbol.iterator屬性的元素都是可迭代的。

Array.prototype.newArr = function() {};
const array = ['foo', 'bar', 'baz'];
for (const value of array) { 
    console.log(value);
}
// Outcome:
// => foo
// => bar
// => baz

for...of不考慮建構函式原型的不可列舉屬性。它只需要查詢可列舉屬性並將其列印出來。

總結

理解for...of迴圈在開發過程中的用法,可以節省很多時間。希望本文能幫助您理解和編寫JavaScript開發中的更好的迴圈結構。從而讓你編碼更快樂!

相關免費學習推薦:

以上就是深入瞭解JS中的for...of迴圈的詳細內容,更多請關注TW511.COM其它相關文章!