오늘은 for...of 구문에 대해 알아보도록 하겠습니다. for...of는 반복가능한(iterable) 객체(Array, Map, Set, String, TypedArray, arguments 객체등을 포함)에 대해서 반복하고 각 개발 속성값에 대해 실행되는 문이 있는 사용자 정의 후크를 호출하는 루프를 생성합니다. 예제를 확인해보며 for of에 대해 알아보도록 하겠습니다.
Array
let iterable = [10, 20, 30];
for (let value of iterable) {
console.log(value);
}
// 10
// 20
// 30
array에서는 array의 값들을 반복합니다. 이전 시간에 let과 const에 대해서 확인했는데, 위 소스에서 let 대신 const를 사용할 수도 있습니다. 단, const를 사용했을 경우 블럭 내부에서 값을 수정할 수는 없습니다.
String
let iterable = "boo";
for (let value of iterable) {
console.log(value);
}
// "b"
// "o"
// "o"
String도 for...of 구문을 이용하여 반복할 수 있습니다. String을 반복할 경우 각각의 문자를 반복할 수 있습니다.
TypedArray
let iterable = new Uint8Array([0x00, 0xff]);
for (let value of iterable) {
console.log(value);
}
// 0
// 255
typedArray에 대한 반복도 가능합니다. 위 예제는 Uint8Array를 반복한 예제입니다.
Map
let iterable = new Map([["a", 1], ["b", 2], ["c", 3]]);
for (let entry of iterable) {
console.log(entry);
}
// [a, 1]
// [b, 2]
// [c, 3]
for (let [key, value] of iterable) {
console.log(value);
}
// 1
// 2
// 3
Map에 대한 반복도 가능합니다. Map은 키-값 쌍으로 이루어진 배열이라고 생각하시면 됩니다. 그래서 for...of 구문을 이용하여 반복하면 키-값 쌍을 출력할 수 있습니다. 조금 더 응용하면 이전에 배운 구조 분해 할당을 이용해서 키나 쌍을 분리해서 사용할 수도 있습니다. 위 예제에서 아랫 부분입니다.
Set
let iterable = new Set([1, 1, 2, 2, 3, 3]);
for (let value of iterable) {
console.log(value);
}
// 1
// 2
// 3
Set 또한 반복 가능합니다. Set에 대해서는 다음에 상세하게 배워보도록 하겠습니다.
Dom Collection
// 주의: 이는 NodeList.prototype[Symbol.iterator]가
// 구현된 플랫폼에서만 작동합니다
let articleParagraphs = document.querySelectorAll("article > p");
for (let paragraph of articleParagraphs) {
paragraph.classList.add("read");
}
Dom Collection에 대한 반복도 가능합니다. querySelectorAll()의 결과 값을 순회하며 작업이 가능합니다.
Generator
function* fibonacci() { // 생성기 함수
let [prev, curr] = [1, 1];
while (true) {
[prev, curr] = [curr, prev + curr];
yield curr;
}
}
for (let n of fibonacci()) {
console.log(n);
// 1000에서 수열을 자름
if (n >= 1000) {
break;
}
}
이후에 배우게될 Generator에 대한 반복도 가능합니다. 자세한 내용은 바로 다음 포스팅에 정리될 예정입니다 :)
Iterable Protocol
var iterable = {
[Symbol.iterator]() {
return {
i: 0,
next() {
if (this.i < 3) {
return { value: this.i++, done: false };
}
return { value: undefined, done: true };
}
};
}
};
for (var value of iterable) {
console.log(value);
}
// 0
// 1
// 2
iterable 프로토콜을 명시해서 구현하는 객체도 반복할 수 있습니다. 위 소스에서는 i는 0으로 초기화 하고 next가 호출될 때마다 i를 증가시키고 i가 3보다 클 때 종료되는 iterable 객체를 구현했습니다. 이를 for...of 구문으로 반복하여 결과가 출력된 것을 확인할 수 있습니다.
for...of VS for...in
그렇다면 비슷한 for...in 구문과는 어떤 차이가 있을까요?
먼저 for...in은 객체의 모든 열거가능한 속성에 대해 반복합니다. 그에 반해 for...of 구문은 걸렉션 전용으로 모든 객체가 아닌 [Symbol.iterator] 속성이 있는 모든 컬렉션 요소에 대해 반복합니다.
Object.prototype.objCustom = function () {};
Array.prototype.arrCustom = function () {};
let iterable = [3, 5, 7];
iterable.foo = "hello";
for (let i in iterable) {
console.log(i); // logs 0, 1, 2, "foo", "arrCustom", "objCustom"
}
for (let i of iterable) {
console.log(i); // logs 3, 5, 7
}
위 코드를 보면 그 차이를 확인할 수 있습니다. for...in은 모든 열거가능한 속성에 대해 반복했습니다. 그래서 속성들의 키 값들이 출력된 것을 확인할 수 있습니다. for...of 구문은 내부 속성들중 열거가능한 컬렉션 요소를 순회하며 그 값을 출력해준 것을 확인할 수 있습니다.
참고:
developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Statements/for...of
'JavaScript' 카테고리의 다른 글
[ES 6 JavaScript] Map (0) | 2020.10.10 |
---|---|
[ES6 JavaScript] Generator (0) | 2020.10.07 |
[ES6 JavaScript] let, const (0) | 2020.10.05 |
[ES6 JavaScript] Spread syntax(전개 구문) (0) | 2020.10.04 |
[ES6 JavaScript] Rest Parameters (0) | 2020.10.03 |