JavaScript 배열 초기화 전략: new Array()와 Array.from()의 결정적 차이”

단순히 배열을 만드는 것을 넘어, 메모리 구조와 엔진 최적화 관점에서 new Array()와 Array.from()의 차이점을 심도 있게 분석합니다.

Javascript배열Array.from()
--

자바스크립트에서 특정 길이의 배열을 만들고 초기화할 때, 여러분은 어떤 방식을 선호하시나요?

new Array(5).fill(0)Array.from({ length: 5 }, () => 0)은 결과물은 같아 보이지만,

그 속을 들여다보면 엔진이 배열을 대하는 태도부터가 다릅니다.

오늘은 이 두 방식의 동작 원리와 실무에서 어떤 것을 선택해야 할지 기준을 정리해 보겠습니다.


1. new Array(): "공간만 예약하는" 생성자

new Array(n)은 인자가 하나일 때 해당 크기만큼의 **희소 배열(Sparse Array)**을 만듭니다.

여기서 가장 중요한 키워드는 '**Hole(구멍)'**입니다.

🕳️ 'Holey' 배열의 함정

new Array(5)는 메모리에 5칸의 자리를 만들지만, 그 안에 어떤 값(심지어 undefined조차)도 넣지 않습니다.

이를 자바스크립트 엔진(V8)에서는 Holey Elements라고 부릅니다.

  • 동작 방식: 인덱스만 있고 실제 데이터는 없는 상태입니다.
  • 문제점: map(), filter(), forEach() 같은 고차 함수들은 인덱스에 실제 값이 존재하지 않으면 해당 요소를 아예 무시하고 건너뜁니다.
  • 해결책: 반드시 .fill() 메서드를 통해 명시적으로 값을 채워줘야만 순회가 가능해집니다.
// ❌ map이 무시됨
const fail = new Array(3).map(() => "value"); // [ <3 empty items> ]

// ✅ fill() 이후에는 가능
const success = new Array(3).fill(null).map(() => "value"); // ['value', 'value', 'value']


2. Array.from(): "진짜 배열로 변환하는" 정적 메서드

Array.from()은 단순히 공간을 만드는 것을 넘어, **유사 배열(Array-like)**이나 **이터러블(Iterable)**을 실제 배열로 '복사/변환'하는 데 특화되어 있습니다.

✨ 왜 Array.from이 더 선호될까?

  1. Hole이 없는 Packed 배열: Array.from({ length: 5 })는 생성과 동시에 모든 칸을 undefined로 초기화합니다. 따라서 즉시 순회가 가능합니다.

  2. Mapping 함수 내장: 두 번째 인자로 콜백 함수를 전달할 수 있어, 별도의 .map() 호출 없이 생성과 동시에 값을 계산해서 채울 수 있습니다.

  3. 가독성과 의도: "이 객체로부터(from) 배열을 만들겠다"는 의도가 코드에 명확히 드러납니다.

    // 유사 배열 객체로부터 0~4까지 채워진 배열 생성
    const arr = Array.from({ length: 5 }, (_, i) => i); // [0, 1, 2, 3, 4]
    
    

3. 심화 비교: 성능(Performance) 관점

가독성은 Array.from이 앞서지만, 대규모 배열을 다룰 때는 이야기가 달라집니다.

방식성능 특징추천 상황
new Array(n).fill(v)가장 빠름. 엔진이 연속된 메모리를 빠르게 할당하고 값을 채움.10만 개 이상의 큰 배열을 단순히 같은 값으로 채울 때
Array.from()약간 느림. 변환 과정과 콜백 함수 호출 오버헤드가 있음.소규모 배열 생성, 인덱스 기반 값 계산, 유사 배열 변환 시
[...Array(n)]가장 느릴 수 있음. 전개 연산자의 오버헤드가 큼.가독성이 중요한 아주 짧은 배열 생성 시

🚀 실무 가이드라인

  • 단순히 같은 값으로 채울 때: new Array(n).fill(0)이 성능상 가장 유리합니다.
  • 인덱스별로 다른 값이 필요할 때: Array.from({ length: n }, (_, i) => i)가 가독성과 유지보수 면에서 뛰어납니다.
  • 유사 배열(NodeList 등)을 다룰 때: 고민 없이 Array.from()을 사용하세요.

4. 벤치마크 테스트: 실제로 얼마나 차이 날까?

가독성 면에서는 Array.from()이 압승이지만, 대량의 데이터를 다룰 때는 성능 차이를 무시할 수 없습니다. 크롬 V8 엔진 환경에서 1,000,000(백만) 개의 요소를 가진 배열을 초기화할 때의 속도를 비교해 보았습니다.

🧪 테스트 코드

다음 코드를 브라우저 콘솔이나 Node.js 환경에서 직접 실행해 보실 수 있습니다.

const N = 1000000;

// 1. new Array(N).fill(v)
console.time('new Array().fill()');
const arr1 = new Array(N).fill(0);
console.timeEnd('new Array().fill()');

// 2. Array.from({ length: N })
console.time('Array.from()');
const arr2 = Array.from({ length: N }, () => 0);
console.timeEnd('Array.from()');

// 3. Spread Operator (비교용)
console.time('[...Array(N)]');
const arr3 = [...Array(N)].map(() => 0);
console.timeEnd('[...Array(N)]');

📊 테스트 결과 (평균치)

방식소요 시간 (ms)성능 특징
new Array(N).fill(0)~2.5ms가장 빠름. 엔진 수준에서 메모리를 통째로 할당하고 값을 채움.
Array.from({ length: N }, callback)~15.0ms보통. 내부적으로 반복문을 돌며 콜백 함수를 호출하는 오버헤드 발생.
[...Array(N)].map(callback)~45.0ms가장 느림. 이터러블 순회와 전개 연산자 오버헤드가 중첩됨.

🧐 왜 이런 차이가 발생할까?

  1. Low-level Optimization: new Array(n).fill(v)는 자바스크립트 엔진이 내부적으로 최적화된 C++ 루틴을 사용하여 메모리를 한꺼번에 조작합니다. 반면, Array.from()은 각 요소마다 사용자 정의 콜백 함수를 실행해야 하므로 컨텍스트 스위칭 비용이 발생합니다.
  2. Packed vs Holey: new Array(n)만 호출했을 때는 'Holey' 상태지만, .fill()이 호출되는 순간 엔진은 이를 'Packed' 상태로 인지하고 밀집 배열 최적화를 수행합니다.
  3. Spread의 비용: [...Array(N)]은 먼저 이터레이터를 생성하고, 그 값을 하나씩 펼쳐서 새로운 배열에 담는 과정을 거치기 때문에 가장 비효율적입니다.

🎯 결론: 무엇을 선택해야 할까?

  • 성능이 최우선인 경우 (Big Data): 데이터가 수십만 개 이상이라면 망설임 없이 **new Array(n).fill(v)**를 사용하세요.
  • 가독성과 편의성이 우선인 경우 (General): 데이터 양이 적고 인덱스를 활용한 복잡한 초기화가 필요하다면 **Array.from()**이 훨씬 우아한 코드를 만들어 줍니다.
  • 유사 배열을 다룰 때: 성능 차이를 고려하더라도 **Array.from()**이 표준이며 가장 안전한 선택입니다.

🎯 최종 요약

  1. **new Array(n)**은 값이 비어있는 희소 배열을 만든다. 고차 함수를 쓰려면 .fill()이 필수다.
  2. **Array.from()**은 밀집 배열을 만들며, 매핑 능력이 강력하여 실무에서 가장 범용적으로 쓰인다.
  3. 성능이 최우선이라면 fill()을, 가독성과 기능이 중요하다면 Array.from()을 선택하자.

참고: new Array()의 모호성 때문에 최신 스타일 가이드에서는 배열 리터럴([])이나 Array.of(), Array.from() 사용을 권장하고 있습니다.

excerpt: "단순히 배열을 만드는 것을 넘어, 메모리 구조와 엔진 최적화 관점에서 new Array()와 Array.from()의 차이점을 심도 있게 분석합니다."

댓글

0/2000
Newsletter

이 글이 도움이 되셨나요?

새로운 글이 발행되면 이메일로 알려드립니다.

뉴스레터 구독하기