221209 TIL for/of 문과 for/in 문의 차이점

for/of 문

let o = [ 1, 2, 3 ];
for(a of o) {
    console.log(a);
}
  • ES6에서 새로 등장한 문법이다
  • iterable 객체에서 동작한다.
    • 배열, 문자열, 세트, 맵
    • 객체는 기본적으로 이터러블이 아니기 때문에 for/of를 사용하고 싶다면 Object.keys() 또는 Object.entries()를 사용해야 한다.
  • 배열은 동적으로 순회한다.
    • 반복 중간에 배열 자체에 변화가 생기면 반복 결과가 바뀌기도 한다.
    • for/of문을 도는 도중 중간에 배열 자체에 변화가 발생한다면
let data = [1, 2, 3, 4, 5], sum = 0;
let i = 0;
for(let elem of data) {
    i++
    sum += elem;
    data.push(sum);
    console.log(elem);
    if(i > 1000) break;
}

무한으로 쌓이는 console.log를 볼 수 있다.

image

break를 걸어서 망정이지 안 걸고 실행하면 무한 루프가 실행되며 브라우저가 종료된다.

for/in 문

let o = { x: 1, y: 2, z: 3};
for(a in o) {
    console.log(a);
}
  • 자바스크립트 초창기부터 존재한 문법이다.
  • for/of와 거의 비슷하지만, for/in은 어떤 객체든 사용할 수 있다.
  • 자바스크립트 인터프리터는 for/in을 실행할 때 첫 번째로 object 표현식을 평가한다.
    • null이나 undefined로 평가될 경우 인터프리터는 루프를 건너뛰고 다음 문으로 이동한다.
  • 왼쪽 값으로 평가될 수 있다면 어떤 표현식을 써도 된다.

이와 같은 특징을 이용하여 객체 프로퍼티 이름을 배열에 복사할 수도 있다.

let o = { x: 1, y: 2, z: 3};
let a = [], i = 0;
for(a[i++] in o) {}
a // => ['x', 'y', 'z']

자바스크립트 배열은 for/in 루프에서 열거할 수 있는 객체 프로퍼티이다.

let o = [1,2,3];
for(a in o) {
    console.log(a); // => 0, 1, 2
		console.log(o[a]); // => 1, 2, 3: 값을 출력하고 싶다면 이렇게
}

❇️  배열을 대상으로 작업할 때는 대부분 for/of를 사용한다.

for/in 루프는 실제로 객체의 프로퍼티 전체를 열거하지는 않는다.

  • 이름이 심벌인 프로퍼티는 열거하지 않는다.
  • 이름이 문자열인 프로퍼티 중에서도 열거 가능한 프로퍼티만 순회한다.
    • 내장 메서드인 toString()은 열거 불가이기 때문에 열거하지 않는다.
  • 열거 가능한 상속된 프로퍼티는 for/in 루프의 순회 대상이다.
    • 이 때문에 for/in 대신 Object.keys()와 for/of 루프 조합이 선호된다.