Abstract Loop & Lazy Execution - Generator로 코드 줄이기
Iterable은 Generator로 코드를 쉽게 줄일 수 있다는 것을 알고 있을 것이다.
아래 코드도 줄일 수 있다.
- Generator :iterator result object를 만들어준다.
const Compx = class{
constructor(data) {this.data = data;}
[Symbol.iterator](){
const data = [JSON.parse(JSON.stringify(this.data))];
return {
next(){
let v;
while (v = data.shift()) {
if (!(v instanceof Object)) return {value:v};
if (!Array.isArray(v)) v = Object.values(v);
data.unshift(...v);
}
return {done: true};
}
};
}
};
const a = new Compx([{a:[1,2,3,4], b:'-'}, [5,6,7], 8,9]);
console.log([...a]);
console.log([...a]);
위 코드를 Generator를 활용해 줄여보자.
const Compx = class {
constructor(data) {this.data = data;}
*gene(){
const data = [JSON.parse(JSON.stringify(this.data))];
let v;
while (v = data.shift()) {
// if일 때와 else일 때를 명확하게 분리
// 객체인 경우와 아닌 경우
if (!(v instanceof Object)) yield v;
else {
// 객체인 경우 중에서 배열인 경우와 아닌 경우
// 배열이 아니라면 배열로 만들고,
if (!Array.isArray(v)) v = Object.values(v);
// 언제나 unshift하는 mandatory(필수) 로직이 옴
data.unshift(...v);
}
}
}
};
const a = new Compx([{a:[1,2,3,4], b:'-'}, [5,6,7], 8,9]);
// Generator 자체는 문법적 혜택을 볼 수 없다.
// 그렇기 때문에 yield를 통해서 iterator result object (value랑 done이란 키를 가지고있는 객체)를 반환해야된다.
// iterable은 iterator result object를 반환하는 next 메서드를 반환하는 Symbol.iterator 메서드를 가지고있는 객체이다.
// 차이점 숙지~!
// 여튼 아래와 같이 iterator result object를 반환하도록 작성해야 문법적 혜택을 볼 수 있다.
// 아래 식이 위와 같은 이유로 아래처럼 작성된 것이다.
console.log([...a.gene()]); // [1,2,3,4,'-',5,6,7,8,9]
console.log([...a.gene()]); // [1,2,3,4,'-',5,6,7,8,9]
if 문 - mandatory(필수적으로 실행되어야하는 코드), optional(선택적으로 실행되어야 하는 코드) - 누가봐도 명확하게 작성되어야한다.