일반for문 vs. for in문

|

일반for문

자바스크립트에서 for 문은 반복적인 동작을 수행하는 데 사용되며, 초기화식, 검사식, 증가식으로 세 부분으로 구성된다. 문법은 다음과 같다.

for (초기화식, 검사식, 증가식){
    구문
}
  • 초기화식은 반복문이 시작하기 전에 한 번만 평가된다.
  • 검사식은 각 반복에 앞서 평가되며 반복문의 본문이 실행될지 여부를 좌우한다. 검사식이 참이면 반복문의 본문에 해당하는 구문이 실행된다.
  • 증가식은 각 반복이 끝날 때마다 평가된다.

 

for in 문

자바스크립트에서 for...in 문은 객체의 프로퍼티를 순회하는 데 사용된다. 문법은 다음과 같다.

for (변수 in 객체){
    구문
}
  • for...in 문의 본문은 객체의 각 프로퍼티에 대해 한 번씩 실행된다.
  • 각 반복에 앞서 객체 프로퍼티 중 하나의 이름이 변수에 문자열 타입으로 할당된다.
  • 일반 object의 문자열 키를 순회하기 위해 만들어진 문법!
  • 프로토타입 체인을 모두 탐색하므로 hasOwnProperty 로 필터링 해야 에러 및 속도개선이 됨!
  • (JavaScript는 Java와 다르게 프로토타입 을 통해 상속을 사용하는데, for in 문은 객체의 각 프로퍼티에 접근하려고 하면 JavaScript는 해당 이름의 프로퍼티를 찾을 때까지 프로토타입 체인을 거슬러 올라가면서 탐색하게 됨. 없는 프로퍼티에 접근하려고 하면 항상 프로토타입 체인 전체를 탐색하게 됨. ) 
// 객체 정의
var person = { hand: 2, legs: 2, head: 1 };

// 코드 어딘가에서 모든 객체에 아래와 같은 메서드 하나가 추가되었다고 해보자.
if (typeof Object.prototype.clone === 'undefined') {
	Object.prototype.clone = function () {
 		// 메소드 로직 생략
	};
}

for (var prop in person) {
	console.log(prop, ":", person[prop]);
}

// 콘솔에 출력결과는 다음과 같다.

/* 
   hand : 2
   legs : 2
   head : 1
   clone : () {
   // 메소드 로직 생략
   }
*/

person 을 정의하기 전이나 후,
어디선가 Object 프로토타입에 clone() 이라는 이름의 메서드가 편의상 추가되었다고 했을때
프로토타입 체인의 변경 사항은 실시간으로 반영되기 때문에
자동적으로 모든 객체가 이 새로운 메서드를 사용할 수 있습니다.

person 을 열거할 때 clone() 메서드가 나오지 않게 하려면 프로토타입 프로퍼티를 걸러내기 위해
hasOwnProperty() 를 호출해야 합니다.
이렇게 걸러내지 않으면 clone() 이 나오게 되는데, 대부분의 경우 이러한 동작 방식은 바람직하지 않습니다.
seiresMap = {
	"A001": {name: "소정", data: Array(12)},
	"B001": {name: "시간외", data: Array(12)}
    }

seriesMap이 위와 같이 구성된 경우 for in문으로 작동이 되고,
일반 for문에선 // for ( i = 0, len = seriesMap.length; i < len; i++ ) {
작동하지 않는다.

            for ( i in seriesMap ) {
                res.push( {
                    name: seriesMap[ i ].name,
                    data: seriesMap[ i ].data,
                    categories: categories,
                    type: "bar",
                    stack: info.yAxisTitle
                } );
            }

 

And