1st 코드로그 · Array 메서드와 Professor Lee(feat. Team 5 지훈님)

허정석·2025년 7월 14일

TIL

목록 보기
1/19
post-thumbnail

2025-07-14 (월)

✅ 오늘 배운 것

  • Array.prototype.flat() (처음 알고 써봄)
  • 개념 및 동작 방식
    • 평탄화: 중첩된 배열 구조를 '평평하게' 펴서 새로운 1차원 배열로 만들어주는 역할
    • 렌더링 로직을 단순하고 예측 가능하게 만드는 중요한 전처리 과정
   1 // children 배열 (flat() 적용 전)
   2 [
   3   { type: 'p', ... },  // VNode 객체
   4   [                     // 중첩된 배열
   5     { type: 'span', ... },
   6     { type: 'span', ... }
   7   ],
   8   { type: 'p', ... }   // VNode 객체
   9 ]


   1 // children.flat() 적용 후
   2 [
   3   { type: 'p', ... },
   4   { type: 'span', ... }, // 배열이 풀려서 VNode 객체만 남음
   5   { type: 'span', ... },
   6   { type: 'p', ... }
   7 ]

위는 쨰미나이가 나에게 평탄화를 설명하기 위해 만들어준 예시 코드이다. 평탄화..말만 들어도 그냥 뭔가 평평하게 만들어주는거로 인식했다.
역시나 위 개념에서 보이는 그대로 중첩된 배열 구조를 평평하게 만드는 작업 이였다.
근데... 왜 하필 지금 여기서 평탄화가 나왔나? 발단은 Virtual DOM 상세 수도코드(feat.준형님) 였다..... 2주차 과제에 포함되는 내용이라서 이게 뭐지 하면서 찾아봤다.

사용법

flat()
flat(depth)

위 코드처럼 매개변수 없이 호출하여 사용하면 기본 1 depth로 평탄화를 진행하며, depth 의 값 만큼 구조를 평탄화 해주는 메소드이다.

const arr1 = [1, 2, [3, 4]];
arr1.flat();
// [1, 2, 3, 4]

const arr2 = [1, 2, [3, 4, [5, 6]]];
arr2.flat();
// [1, 2, 3, 4, [5, 6]]

const arr3 = [1, 2, [3, 4, [5, 6]]];
arr3.flat(2);
// [1, 2, 3, 4, 5, 6]

const arr4 = [1, 2, [3, 4, [5, 6, [7, 8, [9, 10]]]]];
arr4.flat(Infinity);
// [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

Infinity

  • 배열의 중첩 깊이를 전혀 예측할 수 없거나, 신경 쓰고 싶지 않을 때 사용합니다.
  • 데이터의 구조적 의미가 완전히 사라져도 상관없는, 단순한 값들의 목록을 다룰 때 유용합니다.

MDN_Array.prototype.flat()


💡 깨달은 점

// createVNode.js
/**
 * 가상 DOM 생성
 * 실제 DOM으로 렌더링 할 때 필요한 모든 정보를 담고 있어야 함
 * */
export function createVNode(type, props, ...children) {
  children = [
    ...children.filter((child) => child !== null && child !== undefined && child !== false && child !== true),
  ];
  function getArrayDepth(array) {
    if (!Array.isArray(array)) {
      return 1;
    }

    let max = 1;
    for (const arrayElement of array) {
      const currentDepth = getArrayDepth(arrayElement);

      if (currentDepth + 1 > max) {
        max = currentDepth + 1;
      }
    }
    return max;
  }
  const threshold = 2; // 기준 임계치
  const depth = getArrayDepth(children);

  return { type, props, children: children.flat(threshold < depth ? Infinity : depth) };
}


"올바른 구조의 vNode를 생성해야 한다"
"여러 자식을 처리해야 한다"
"자식 배열을 평탄화해야 한다"
"중첩 구조를 올바르게 표현해야 한다"
"JSX로 표현한 결과가 createVNode 함수 호출과 동일해야 한다"

위는 나의 코드와 해당 챕터의 통과 기준이다.

작성 코드와 테스트 통과 기준에서 이질감이 들어보인다.
왜냐하면 테스트에서 "평탄화를 해야한다"고 명시했고 개발자는 이 규칙에 맞게 코드를 작성하게 될 것이다.(복잡한 구조 또는 불확실하게 자식 배열을 보내지 않을 것) 그치만 나는 이것을 간과했다. children 에 어떤 것이 들어와도 다 잘해보이겠어. 라는 마인드에 사로잡혀 코드를 작성했다. 또한 해당 코드는 가상 DOM 을 그려주는데 있어 미세한 성능 부하가 발생할 수 있다.

나 스스로가 어떤 것을 바라볼 때 간단하게 바라보지 않는다는 것을 깨달았다. 그리고 테스트의 의도를 명확하게 파악하지 못한다는 점이다.
리팩토링은 추후에 꼭 진행하기...!


😵 오늘 나를 당황시킨 것들

1. 쨰미나이의 평가

Gemini:
이 createVNode.js 파일은 단순한 VNode 생성을 넘어, 입력 데이터(특히 children)의 불확실성에
대응하는 다양한 방어적/최적화 로직이 포함된 매우 견고한 팩토리입니다. 특히 getArrayDepth를 활용한
동적 평탄화는 다른 간단한 VDOM 구현에서는 보기 드문 독창적이고 인상적인 부분입니다.

2. 지훈님의 질문

보기 드문 독창적이고 인상적인 부분이다....아마 지훈님도 getArrayDepth 가 어색하게 느껴져서인지 나에게 아래 질문을 했다.(질문 더 많았음.. 훨씬..)
1. 함수를 생성한 이유
2. flat()을 더 잘 사용하려면 어떻게 해야하는가

당연히 한 번도 써보지 않은 메소드 이기에 "어버버" 댔다... 지훈님은 조리있게 본인의 생각을 얘기하셨다. 그리고 그런 대화가 끝난 뒤의 대화이다.
지훈님과의대화

이래저래 당황 많이 했다..

🎯 내일의 나에게

  • 테스트 코드 의도 파악
  • 복잡하게 생각하지 말기
  • 지훈님에게 컨펌 받기

✍️ 한 줄 회고

K.I.S.S (Keep It Simple, Stupid)

👉 “바보처럼 간단하게 만들어라” (“되도록 단순하게 유지하자”)

6개의 댓글

comment-user-thumbnail
2025년 7월 14일

같이 하루 하루 성장해요

1개의 답글
comment-user-thumbnail
2025년 7월 14일

크 잘봤습니당 깨달음을 얻으시는 정석님 최고

1개의 답글
comment-user-thumbnail
2025년 7월 14일

ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ재밌다

1개의 답글