배열은 0번부터 번호가 붙은 칸입니다
번호로 값을 읽고, 끝에 값을 붙이고, 가운데 값을 지울 때 칸이 어떻게 달라지는지 한 단계씩 확인합니다.

모든 예제는 브라우저 개발자 도구의 Console에서 각각 독립적으로 실행합니다. 여러 예제를 차례로 붙여 넣다가 Identifier has already been declared가 나오면 페이지를 새로고침한 뒤 다음 예제를 실행하세요.
1. 사물함 번호처럼 생각해 봅니다
장바구니에 우유, 빵, 사과를 차례대로 담았습니다. JavaScript 배열은 첫 칸부터 0, 1, 2라는 번호를 붙입니다. 이 번호를 인덱스라고 합니다.
| 인덱스 | 0 | 1 | 2 |
|---|---|---|---|
| 값 | 우유 | 빵 | 사과 |
사람은 첫 번째를 1이라고 부르는 일이 많지만, 배열의 첫 번째 칸은 0입니다. 그래서 두 번째 값인 빵을 읽을 때는 cart[1]이라고 씁니다.
2. 번호로 값을 읽습니다
const cart = ['우유', '빵', '사과'];
console.log(cart[0]);
console.log(cart[1]);
console.log(cart.length);
우유 빵 3
첫 줄은 배열을 만들고 cart라는 이름을 붙입니다. cart[0]은 0번 칸, 즉 첫 값을 읽습니다. cart[1]은 1번 칸, 즉 두 번째 값을 읽습니다. length는 값이 몇 개인지 알려주므로 3입니다. 값을 읽기만 했기 때문에 배열 내용은 바뀌지 않습니다.
작은 확인 문제: 사과의 인덱스는?
정답은 2입니다. 값이 세 개여도 인덱스는 0, 1, 2가 됩니다.
const fruits = ['우유', '빵', '사과'];
console.log(fruits[2]);
사과
3. 끝에 값을 하나 추가합니다
push는 배열의 끝에 새 값을 붙입니다.
| 단계 | 배열 | 새 값의 인덱스 |
|---|---|---|
| 추가 전 | [우유, 빵, 사과] | – |
| 달걀을 끝에 추가 | [우유, 빵, 사과, 달걀] | 3 |
| 현재 길이 | 값 4개 | 마지막 인덱스는 3 |
const foods = ['우유', '빵', '사과'];
foods.push('달걀');
console.log(foods.join(', '));
console.log(foods[3]);
우유, 빵, 사과, 달걀 달걀
첫 줄에서 값은 세 개입니다. 두 번째 줄이 달걀을 끝에 붙입니다. 기존 값의 인덱스는 그대로이고 달걀이 새 3번 칸을 받습니다. 마지막 두 줄은 바뀐 배열과 3번 칸을 확인합니다.
join(', ')은 배열의 값을 쉼표로 이어 출력하기 위한 표현입니다. 값을 넣거나 빼지 않습니다. 이 절에서는 push가 실제 배열을 바꾸고, join은 바뀐 모습을 보여 주기만 한다는 차이를 기억하세요.
4. 가운데 값을 지우면 뒤 값이 앞으로 옵니다
빵을 지운다고 해보겠습니다. 빵은 1번 칸에 있습니다. 빈 칸을 그대로 두지 않기 위해 뒤에 있던 사과와 달걀의 번호가 하나씩 작아집니다.
| 단계 | 0번 | 1번 | 2번 | 3번 |
|---|---|---|---|---|
| 삭제 전 | 우유 | 빵 | 사과 | 달걀 |
| 1번 삭제 직후 생각 | 우유 | (빈칸) | 사과 | 달걀 |
| 정리 후 | 우유 | 사과 | 달걀 | – |
const basket = ['우유', '빵', '사과', '달걀'];
basket.splice(1, 1);
console.log(basket.join(', '));
console.log(basket[1]);
우유, 사과, 달걀 사과
splice(1, 1)에서 첫 번째 1은 “1번 인덱스부터”, 두 번째 1은 “값 한 개를” 뜻합니다. 빵이 빠지고 사과는 2번에서 1번으로, 달걀은 3번에서 2번으로 이동합니다. splice는 원본 배열 자체를 바꿉니다.
작은 확인 문제: 가운데에 값을 넣으면?
colors.splice(1, 0, '초록')을 실행하면 1번 칸부터 0개를 지우고 초록을 넣습니다.
const colors = ['빨강', '파랑'];
colors.splice(1, 0, '초록');
console.log(colors.join(', '));
빨강, 초록, 파랑
파랑이 1번에서 2번으로 밀리고, 초록이 1번 칸을 차지합니다.
5. 지금까지의 선택 기준을 정리합니다
| 동작 | 배열에서 일어나는 일 |
|---|---|
cart[1] |
번호가 정해져 있어 해당 칸을 바로 읽음 |
push('달걀') |
끝에 새 칸을 붙임 |
splice(1, 1) |
1번 값을 지우고 뒤 값을 앞으로 당김 |
따라서 번호로 자주 읽고 끝에 자주 추가한다면 배열이 편합니다. 반대로 앞이나 가운데에서 값을 계속 지우면 뒤의 많은 값이 자리를 옮길 수 있습니다. 먼저 들어온 값을 계속 꺼내는 일이라면 큐가 더 자연스럽습니다.
6. 심화: 원본을 바꾸지 않고 첫 값만 제거하기
더 알아보기: 원본을 유지하는 완성 함수
아래는 선택 심화 예제입니다. 같은 값이 여러 번 있어도 처음 만난 값 하나만 빼고 새 배열을 만듭니다. 원본 배열은 유지합니다.
function removeFirst(values, target) {
const index = values.indexOf(target);
if (index === -1) return values.slice();
return [...values.slice(0, index), ...values.slice(index + 1)];
}
const source = [4, 2, 4, 1];
console.log(JSON.stringify(removeFirst(source, 4)));
console.log(JSON.stringify(source));
[2,4,1] [4,2,4,1]
indexOf는 왼쪽부터 4를 찾아 인덱스 0을 돌려줍니다. slice(0, index)는 삭제할 값 앞쪽을, slice(index + 1)는 뒤쪽을 복사합니다. 두 조각을 합치므로 첫 번째 4만 빠집니다. 값이 없을 때 index는 -1이므로 아무것도 지우지 않고 slice()로 복사본을 돌려줍니다.
이 함수는 원소가 많을수록 찾고 복사할 값도 늘어납니다. 가운데 삭제가 단순한 “한 칸 비우기”가 아니라 뒤 값의 위치를 정리하는 작업이라는 점이 핵심입니다. 객체가 들어 있다면 배열 껍데기만 새로 만들며 객체 자체까지 복제하지는 않습니다.
7. 연습으로 연결합니다
기존 문제 JavaScript 배열 최솟값 찾기에서 0번부터 마지막 인덱스까지 차례로 읽어 보세요. 다른 구조와 비교하고 싶다면 어떤 자료구조를 고를까?로 돌아갈 수 있습니다.
참고 자료
공식 문서 확인일: 2026년 9월 10일.
직접 실습: 연산 비용으로 구조를 설명합니다
실습 주제: JavaScript 배열: 인덱스 조회와 삽입·삭제 비용
- 본문 구현에서 저장되는 값과 연결 관계를 그림으로 적습니다.
- 조회·삽입·삭제 중 이 구조가 가장 자주 수행할 연산을 고릅니다.
- 연산 전후에도 유지되어야 하는 규칙을 한 문장으로 적습니다.
- 배열이나 Map 같은 다른 구조로 바꿨을 때 시간·공간 비용을 비교합니다.
풀이 기준과 확인 결과
메서드 이름만 외우지 말고 한 번의 연산에서 어떤 값과 연결이 바뀌는지 추적하세요. 빈 구조, 원소 한 개, 중복값, 연속 삽입·삭제를 실행했을 때 본문이 설명한 불변식이 유지되면 성공입니다.
테스트 체크리스트
- 빈 구조에 대한 조회·삭제 처리
- 첫 원소와 마지막 원소 변경
- 중복값 또는 동일 우선순위 처리
- 입력 크기가 커졌을 때 예상 복잡도 유지
이 글이 도움이 되었나요?
자료구조 학습 순서
필수 18개 · 전체 18개
읽음 기록 관리
전체 과정 목차 (18개)
- 필수 학습 · 자료구조 선택 가이드: 연산 비용으로 배열·스택·큐·Set 고르기
- 필수 학습 · JavaScript 배열: 인덱스 조회와 삽입·삭제 비용 현재 글
- 필수 학습 · JavaScript Map·Set: 값 조회와 중복 제거 실습
- 필수 학습 · 자료구조 스택 쉽게 이해하기: push pop으로 문제 풀이 감 잡기
- 필수 학습 · 큐와 FIFO: head 인덱스로 JavaScript 대기열 만들기
- 필수 학습 · 단방향 연결 리스트: head·tail 삽입과 삭제
- 필수 학습 · JavaScript 원형 덱 구현: 양끝 삽입·삭제와 고정 용량 버퍼
- 필수 학습 · JavaScript 문자열 해시 테이블 구현: 충돌 처리와 리사이즈, NFC 정규화
- 필수 학습 · 트리 자료구조 차이: 이진 트리 BST MST 구분하기
- 필수 학습 · JavaScript 이진 탐색 트리 구현: 중복 키와 세 가지 삭제 처리
- 필수 학습 · JavaScript 최소 힙 구현: 우선순위 큐의 push·pop과 비교 함수
- 필수 학습 · JavaScript 그래프 구현: 인접 리스트·인접 행렬 비교와 BFS
- 필수 학습 · JavaScript Union-Find: 경로 압축과 크기 합치기로 연결 상태 관리하기
- 필수 학습 · JavaScript Trie: Unicode 접두사 검색과 안전한 삭제 구현
- 필수 학습 · JavaScript Fenwick Tree: lowbit로 구간 합과 단일 증가 갱신 구현
- 필수 학습 · JavaScript 반복형 세그먼트 트리: 구간 합·단일 대입·결합 순서
- 필수 학습 · JavaScript LRU 캐시: Map과 이중 연결 리스트의 불변식
- 필수 학습 · JavaScript AVL 트리: 높이 불변식과 LL·RR·LR·RL 삽입 회전
새 글 받아보기
RSS 리더에서 BlogFlow의 새 글을 확인할 수 있습니다.