Javascript

호이스팅: 아래에 함수를 선언해도 위에서 읽을 수 있는 이유

becky(지은) 2023. 7. 23. 01:36
export default function MonthConsumptionContainer({
  years,
  month,
  setYears,
  setMonth,
  monthSumData,
  groupedData,
  cashGroupedData,
}: {
  years: number;
  month: number;
  setYears: Dispatch<SetStateAction<number>>;
  setMonth: Dispatch<SetStateAction<number>>;
  monthSumData: MonthSumData | Record<string, never>;
  groupedData: GroupedData[];
  cashGroupedData: CashGroupedData[];
}) {
  //6월 데이터와 7월 데이터를 나눠서, 6월 박스의 높이만 커지게 하지 않게 합니다
  const monthData = groupedData.filter(
    (group) => parseInt(group.date.split("-")[1]) === month
  );
  const cashMonthData = cashGroupedData.filter(
    (group) => parseInt(group.date.split("-")[1]) === month
  );

  // 계좌그룹핑 + 현금 그룹핑 데이터 합치기
  const combinedData: CombinedData[] = combineDataByDate(
    monthData,
    cashMonthData
  );
  
  console.log(combinedData);

  return (
    <ConsumptionBox>
      <MonthTopConsumption
        years={years}
        month={month}
        setYears={setYears}
        setMonth={setMonth}
      />
      <MonthConsumptionDetail combinedData={combinedData} />
      <MonthBottomConsumption monthSumData={monthSumData} />
    </ConsumptionBox>
  );
}

/*
{date: '2023-07-01', data: Array(2)} //계좌
{date: '2023-07-01', data: Array(10)} //현금
{date: '2023-07-01', data: Array(12)} 이렇게 나오면 좋겠다
*/

function combineDataByDate(
  monthData: GroupedData[],
  cashMonthData: CashGroupedData[]
): CombinedData[] {

  //빈객체를 초기값으로 설정
  const combinedDataMap:{[date: string]:(MonthConsumptionDataItem|CashMonthConsumptionDataItem)[]} = {};

  //계좌데이터 그룹별로 합치기
  monthData.forEach((group)=>{
  if(!combinedDataMap[group.date]){
    combinedDataMap[group.date] =[];
  }
  combinedDataMap[group.date].push(...group.data);
  });

  //현금데이터 그룹별로 합치기
  cashMonthData.forEach((group)=>{
    if(!combinedDataMap[group.date]){
      combinedDataMap[group.date]=[];
    }
    combinedDataMap[group.date].push(...group.data);
  });

  //CombinedData 형식으로 변환하여 배열담기
  const combinedData = Object.entries(combinedDataMap).map(([date, data])=>({
  date, data
  }))
  return combinedData;
}


{date: '2023-07-01', data: Array(2)} //계좌
{date: '2023-07-01', data: Array(10)} //현금
처럼 date가 같은 경우에는 각각 다른 객체로 존재하는 것이 아니라 하나의 객체로 존재하면 좋겠어서 
(이렇게 {date: '2023-07-01', data: Array(12)} )

기존 데이터를 예쁘게 잘라서, 새로운 객체에 밀어넣는 어려운(?) 함수를 작성해야 했다.
함수를 아래에 선언했는데도 그 위에서 사용가능하다는 이야기는 들어봤으나, 이제야 잘 이해하게 되었다


호이스팅: 함수 선언식은 아래에 선언해도 위에서 읽는 것이 가능하다.
                But, 함수 표현식은 불가능하다



console.log(addNumbers(5, 10)); // 출력: 15

function addNumbers(a: number, b: number): number {
  return a + b;
} 
// 정상적으로 동작한다

console.log(addNumbers(5, 10)); // 오류 발생

const addNumbers = function(a: number, b: number): number {
  return a + b;
};

위의 코드는 오류를 발생시킵니다. 
addNumbers 함수를 호출하려고 할 때 아직 함수가 선언되기 전이기 때문입니다.
따라서 함수 선언문을 사용하는 경우에는 함수를 선언하기 이전에 호출할 수 있지만, 함수 표현식을 사용하는 경우에는 호출하기 이전에 선언하면 오류가 발생합니다.