refer: 為什么說(shuō)for...of循環(huán)是JS中的寶石
Summary
- 簡(jiǎn)明扼要
- 它接受迭代器,包括數(shù)組,字符串,Set,Map,DOM集合
- 它接受類(lèi)數(shù)組對(duì)象
- 迭代的項(xiàng)目可以在就地解構(gòu)
1. 如何判斷數(shù)據(jù)是否可迭代
查看 Symbol.iterator 方法來(lái)確定某個(gè)數(shù)據(jù)是否可迭代。Symbol.iterator 返回一個(gè) iterator對(duì)象。iterator對(duì)象有 next 方法,它會(huì)返回一個(gè)對(duì)象, 對(duì)象當(dāng)中包含value值和boolean類(lèi)型的done。 例如,下面的例子顯示了數(shù)組是可迭代的。
const array = [1, 2, 3];
const iterator1 = array[Symbol.iterator]();
iterator1.next(); // => { value: 1, done: false }
2. 數(shù)組迭代
const products = ['oranges', 'apples'];
for (const product of products) {
console.log(product);
}
// 'oranges'
// 'apples'
此外,數(shù)組方法 entries() 可以用于訪問(wèn)迭代項(xiàng)的索引。該方法在每次迭代時(shí)返回一對(duì) [index,item]。
3. 類(lèi)數(shù)組迭代
function的輸入變量arguments 是函數(shù)體內(nèi)的特殊變量,包含函數(shù)的所有參數(shù),這是一個(gè)經(jīng)典的類(lèi)數(shù)組對(duì)象。
function sum() {
let sum = 0;
for (const number of arguments) {
sum += number;
}
return sum;
}
sum(1, 2, 3); // => 6
4. JavaScript對(duì)象迭代
old way -
const person = {
name: 'John Smith',
job: 'agent'
};
// way one
// forEach
Object.keys(person).forEach(prop => {
console.log(prop, person[prop]);
});
// way two
// for...in + hasOwnProperty
for (let key in person) {
if (person.hasOwnProperty(key)) {
console.log(key, person[key]);
}
}
// 'name', 'John Smith'
// 'job', 'agent'
currently -
const person = {
name: 'John Smith',
job: 'agent'
};
for (const [prop, value] of Object.entries(person)) {
console.log(prop, value);
}
// 'name', 'John Smith'
// 'job', 'agent'
5. Map 和 Set 迭代
Map 是一個(gè)特殊的對(duì)象,將鍵與值相關(guān)聯(lián)。鍵可以是任何基本類(lèi)型(通常是 string,但可以是 number 等)。
幸運(yùn)的是,Map 也是可迭代的(在鍵/值對(duì)上進(jìn)行迭代),并且 for...of 可以輕松地循環(huán)迭代所有鍵/值對(duì)。在每個(gè)循環(huán)中,迭代器都會(huì)返回一個(gè)數(shù)組 [key,value] ,并使用 const [number,name] 立即對(duì)這對(duì)數(shù)組進(jìn)行解構(gòu)。
const names = new Map();
names.set(1, 'one');
names.set(2, 'two');
for (const [key, value] of names) {
console.log(key, name);
}
// logs 1, 'one'
// logs 2, 'two'
7. 遍歷DOM集合
每個(gè) DOM 元素的 children 屬性都是 HTMLCollection 。好在 for...of 可以在類(lèi)似數(shù)組的對(duì)象上進(jìn)行迭代,因此我們可以輕松地迭代 children:
const children = document.body.children;
for (const child of children) {
console.log(child); // logs each child of <body>
}
for...of 可以迭代 NodeList 集合(可迭代)。例如,函數(shù) document.querySelectorAll(query) 返回一個(gè) NodeList:
const allImages = document.querySelectorAll('img');
for (const image of allImages) {
console.log(image); // log each image in the document
}
2.對(duì)象解構(gòu)
for (LeftHandSideExpression of Expression) {
// statements
}
LeftHandSideExpression 表達(dá)式可以替換為任意賦值表達(dá)式左側(cè)的內(nèi)容。
const persons = [
{ name: 'John Smith' },
{ name: 'Jane Doe' }
];
for (const { name } of persons) {
console.log(name);
}
// 'John Smith'
// 'Jane Doe'
8. 性能
迭代大型數(shù)組時(shí),for...of 的執(zhí)行速度可能會(huì)比經(jīng)典方法慢:
const a = [/* big array */];
for (let i = 0; i < a.length; i++) {
console.log(a[i]);
}
在每次迭代中調(diào)用迭代器比通過(guò)增加索引訪問(wèn)的開(kāi)銷(xiāo)更大。但是,這種細(xì)微差別在使用大型數(shù)組的應(yīng)用程序中以及性能至關(guān)重要的應(yīng)用程序中非常重要,不過(guò)這種情況很少發(fā)生。