방명록
- [코디테스트 공부] - JavaScript Array.fill()의 함정 (참조 타입과 원시 타입의 차이)2025년 02월 05일 16시 17분 05초에 업로드 된 글입니다.작성자: 동혁이
JavaScript Array.fill()의 함정 (참조 타입과 원시 타입의 차이)
작성 배경
DFS, BFS와 같은 그래프 알고리즘을 구현하면서 2차원 배열을 만들어 초기화하는 경우가 많습니다.
특히 인접 리스트를 만들거나 방문(boolean) 배열을 초기화할 때 충분히 만날 수 있는 문제라고 생각합니다. (그게 바로 저..)
사전 지식
JavaScript에서 데이터 타입은 크게 두 가지로 나뉠 수 있습니다.
1. 원시 타입 - Number, String, Boolean, null, undefined 등 - 값 자체가 복사됨 2. 참조 타입 - Object, Array 등 - 메모리 주소가 복사됨
예시 코드
// 1. 원시 타입 예시 const 원시타입배열 = new Array(3).fill(false); 원시타입배열[0] = true; console.log(원시타입배열); // 출력: [true, false, false] // 2. 참조 타입 예시 const 참조타입배열 = new Array(3).fill([]); 참조타입배열[0].push(1); console.log(참조타입배열); // 출력: [[1], [1], [1]] // 3. 객체로 보는 더 명확한 예시 const 객체배열 = new Array(3).fill({ count: 0 }); 객체배열[0].count = 1; console.log(객체배열); // 출력: [{ count: 1 }, { count: 1 }, { count: 1 }]
혹시 위 예시 코드를 보고 감이 오시는 분은 굳이 아래까지 안읽으셔도 좋을 것 같습니다!!
여기서 이해가 안되시는 분들이 있기 때문에
메모리 주소를 이용한 예시를 보겠습니다.
// 원시 타입의 경우 const primitive = new Array(3).fill(false); /* 메모리: [false] <- primitive[0] [false] <- primitive[1] [false] <- primitive[2] */ // 참조 타입의 경우 const reference = new Array(3).fill([]); /* 메모리: [](배열) <- 주소1234 [주소1234] <- reference[0] [주소1234] <- reference[1] [주소1234] <- reference[2] */
해결 방법
// 1. map과 화살표 함수 사용 const correct1 = new Array(3).fill(0).map(() => []); // 2. Array.from 사용 const correct2 = Array.from({ length: 3 }, () => []); // 3. 반복문 사용
실제 알고리즘에서 활용 예시
예를 들어, 그래프를 표현하는 인접 리스트를 만들때
// 잘못된 방법 const graph1 = new Array(5).fill([]); // 모든 정점이 같은 배열을 공유 // 올바른 방법 const graph2 = new Array(5).fill(0).map(() => []); // 각 정점이 독립적인 배열을 가짐 // 차이점 확인 graph1[0].push(1); graph2[0].push(1); console.log('잘못된 방법:', graph1); // 출력: [[1], [1], [1], [1], [1]] console.log('올바른 방법:', graph2); // 출력: [[1], [], [], [], []]
결론
fill() 메서드를 사용할 때는 원시 타입과 참조 타입의 차이를 반드시 이해해야 한다는 것을 코딩 테스트 문제를 풀면서 다시 한 번 이해를 하게되었습니다.
2차원 배열이나 객체 배열을 초기화할 때는 map()이나 Array.from()을 사용하여 각 요소가 독립적인 참조를 가지도록 해야 합니다.
이렇게 게시글을 작성해서 이 글을 읽고 계신 분들은 JavaScript의 참조 타입과 원시 타입의 차이를 이해하고, 실제 코딩 테스트나 프로젝트에서 이 지식을 활용 했으면 좋겠습니다!!
다음글이 없습니다.이전글이 없습니다.댓글