-
[ JavaScript ] For in 문 VS For of 문Computer Science/Aws 2023. 11. 11. 23:02
1. for in 문
for in 은 ES1부터 존재했던 방식이며 모든 객체에서 사용이 가능하다.
다만 해당 값의 value는 가져오지 못하며 key 값만 가져올 수 있다.
let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9]; let object = { name: 'Nam', age: 23, city: 'Seoul' }; // 0,1,2,3,4,5,6,7,8 for(let i in arr) { console.log(i); } // name,age,city for(let i in object) { console.log(i); }
더욱이 for in 은 임의로 객체를 순회하여 반환해주기에 순서 등 유의해야한다면 사용하지 말 것을 권장한다.
2. for of 문
iterable 한 객체를 순회할 수 있도록 해준다. ES6 부터 추가된 방식이며 for in 과 다르게 value를 반환해 준다.
let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9]; let object = { name: 'Nam', age: 23, city: 'Seoul' }; // 1,,2,3,4,5,6,7,8,9 for(let i of arr) { console.log(i); } // error for(let i of object) { console.log(i); }
그렇다면 iterable 한 객체란 무엇인가.
iterable한 객체는 배열을 일반화한 객체이다. iterable이라는 개념을 사용하면 어떠한 객체든 for of 문을 사용할 수 있다.
iterable 객체는 Symbol.iterator 라는 메서드가 존재해야한다. 즉 Symbol.iterator가 존재한다면 iterable한 객체라고 할 수 있다.
Symbol.iterator는 반드시 iterator ( next() 가 존재하는 객체 )를 반환해야하며 for of는 반환된 객체 ( iterator ) 만을 대상으로 동작한다.
next()의 반환 값은 반드시 { done: Boolean, value: any } 와 같은 형태여야한다. done은 반복이 종료상태를 의미하며 false일 시에는 다음 값이 존재한다는 뜻이고 true 라면 더이상 값이 존재하지 않는다는 뜻이다. 여기서 조금 생각해볼 것은 반환할 것이 없다면 계속 true 여야 한다는 것이다. 즉 next()를 호출한뒤 done 이 true 인 상태에서 또다시 next()를 호출하면 지속적으로 done이 true여야한다.
한번 객체를 iterable하게 만들어보자.
let object = { name: 'Nam', age: 23, city: 'Seoul' }; object[Symbol.iterator] = function() { let index = 0; let keys = Object.keys(this); return { next: () => { return { value: this[keys[index++]], done: index > keys.length } } } } // Nam, 23, Seoul for(let i of object) { console.log(i); }
object라는 객체에 Symbol.iterator를 추가하였고 Symbol.iterator는 next()를 반환한다. 또한 next() 는 { value: any, done: Boolean } 을 만족하도록 반환한다.
위와 같이 구성한다면 기존에는 동작하지 않았던 for of 문이 동작하는 것을 확인할 수 있다.
어렵게 Symbol.iterator를 직접추가하지 않고 iterator 객체로 만들어주는 것이 있다. Generator 함수라는 것이다.
Generator 함수
Generator 함수는 iterable 객체를 반환하는 특별한 형태의 함수이다.
funtion* 형태로 만들며 yield를 순차적으로 반환한다.
다만 한번만 사용이 가능하며 두번째부터는 사용이 불가능하다.
let object = { name: 'Nam', age: 23, city: 'Seoul' }; function* objToIter(obj) { for(let key of Object.keys(obj)) { yield obj[key]; } } let obj = objToIter(object); // Nam, 23, Seoul for(let i of obj) { console.log(i); } // second start , second end ( not in 및 객체 정보 출력 안됨 ) console.log("second start") for(let i of obj) { console.log("not in") console.log(i); } console.log("second end")
아래와 같이 next를 직접사용해도 마찬가지이며 해당 next가 {done: Boolean, value: any } 형태로 잘 반환하는 것도 확인할 수 있다.
let object = { name: 'Nam', age: 23, city: 'Seoul' }; function* objToIter(obj) { for(let key of Object.keys(obj)) { yield obj[key]; } } let obj = objToIter(object); console.log(obj.next()); // { value: 'Nam', done: false } console.log(obj.next()); // { value: 23, done: false } console.log(obj.next()); // { value: 'Seoul', done: false } console.log(obj.next()); // { value: undefined, done: true } // 반환 x for(let i of obj) { console.log("not in") console.log(i); }
iterable 객체로 만든다면 위와 같이 for of 문을 사용가능할 뿐만아니라 유용한 점들이 생긴다.
예를들어 spread 연산자, 분해대입 등이 있다.
'Computer Science > Aws' 카테고리의 다른 글
eks pod 수 수정 (0) 2023.03.27 AWS 하위 도메인 생성하기. (0) 2022.11.10 AWS Lambda Node.js 로 api call 하기 (0) 2022.09.29 AWS codeDeploy error log 확인 (0) 2022.08.09 AWS Secrets Manager를 이용하여 DB 비밀번호 등 암호화하기. (0) 2022.08.02