7. 여러 개 모아두기 (배열)/7.2 배열에 넣고 빼기

7.2.4 배열의 맨 앞에서 값 꺼내기 - shift()

thejavascript4kids 2025. 7. 8. 03:32

📘 7.2.4 배열의 맨 앞에서 값 꺼내기 - shift()

push, pop, unshift와 함께한 시간들이 차례로 이어져 왔습니다. 이제 우리는 마지막 하나의 이야기를 더 나누어야 할 것 같습니다. 배열의 맨 앞에서 값을 조용히 꺼내오는 shift라는 기능에 대해서 말이지요.

unshift가 배열의 앞에 새로운 값을 넣어주는 일을 한다면, shift는 그와는 정반대로 배열의 맨 앞에 있는 값을 꺼내어 주는 일을 합니다. 마치 줄을 서 있는 사람들 중에서 맨 앞의 사람이 자연스럽게 한 걸음 앞으로 나가는 것처럼요.

shift라는 이름 안에는 "이동한다"는 뜻이 담겨있습니다. 맨 앞의 값이 사라지면서 나머지 값들이 모두 앞으로 한 자리씩 이동하기 때문에 이런 이름을 갖게 되었습니다.

이 기능을 이해하면 우리는 먼저 들어온 것을 먼저 처리하는 자연스러운 시스템을 만들 수 있게 됩니다. 마치 은행에서 대기번호 순서대로 고객을 부르는 것처럼, 차례를 지키며 일을 처리하는 프로그램을 만들 수 있지요.

🧠 새로운 말들과 친해지기

새로운 개념을 만날 때마다, 어려운 단어들이 우리를 멀어지게 하지 않았으면 좋겠습니다. 그래서 이렇게 정리해보았습니다.

단어 따뜻한 설명
shift 배열의 맨 앞에 있는 값을 조심스럽게 꺼내어 우리에게 건네주는 기능입니다.
반환값 shift가 꺼내준 값을 말하며, 그 값을 다른 곳에서 사용할 수 있습니다.
인덱스 당김 맨 앞 값이 사라지면서 나머지 값들이 자연스럽게 한 자리씩 앞으로 이동하는 현상입니다.

✨ shift가 가진 특별함

shift는 pop과 비슷하면서도 정반대의 일을 합니다. pop이 배열의 맨 뒤에서 값을 꺼내주었다면, shift는 맨 앞에서 값을 꺼내어 줍니다.

shift의 가장 흥미로운 점은 맨 앞의 값이 사라지고 나면 나머지 모든 값들이 자동으로 한 칸씩 앞으로 당겨진다는 것입니다. 이는 마치 기차에서 맨 앞 객차가 분리되면 뒤의 객차들이 모두 앞으로 이어지는 것과 같습니다.

pop처럼 shift도 꺼낸 값을 우리에게 돌려주어 다른 곳에서 사용할 수 있게 해줍니다. 만약 배열이 이미 비어있다면, 오류를 일으키지 않고 조용히 undefined를 돌려주어 안전하게 처리할 수 있습니다.

일상의 모습: 우리집 우편함

shift를 더 쉽게 이해하기 위해 일상 속 이야기를 해보겠습니다.

우리집 현관 앞 우편함을 생각해보세요. 우편배달부 아저씨가 우편물을 가져다 주실 때마다 새로운 편지들이 기존 편지들 뒤에 차례로 쌓입니다.

우편물을 확인할 때, 우리는 자연스럽게 가장 먼저 온 편지부터 꺼내어 봅니다. 맨 앞에 있던 편지를 꺼내고 나면, 그 뒤에 있던 편지들이 모두 자연스럽게 한 자리씩 앞으로 밀려나옵니다.

이렇게 하면 편지들이 도착한 순서대로 처리되어, 중요한 편지를 놓치는 일 없이 차례대로 확인할 수 있습니다.

shift가 하는 일이 바로 이런 것입니다. 가장 먼저 들어온 값부터 차례로 꺼내어 주면서, 나머지 값들은 정돈된 순서를 유지하도록 자동으로 정리해주는 것이지요.

🎯 shift를 사용하는 이유

shift가 왜 필요한지 생각해보면, 우리 일상과 많이 닮아있습니다.

가장 대표적인 경우는 "먼저 들어온 것을 먼저 처리"하는 시스템을 만들 때입니다. 병원 대기실에서 순서대로 환자를 호출하거나, 할 일 목록에서 가장 먼저 추가된 일부터 하나씩 완료해나갈 때 사용합니다.

또한 메시지 처리 시스템에서 받은 순서대로 메시지를 처리하거나, 게임에서 플레이어들의 턴을 관리할 때도 유용합니다.

무엇보다 shift를 unshift, push, pop과 함께 사용하면 배열의 모든 방향을 자유롭게 조작할 수 있게 되어, 더욱 복잡하고 실용적인 프로그램을 만들 수 있습니다.

⚙️ shift 사용법 천천히 살펴보기

shift의 사용법은 매우 간단합니다. 마치 한 줄의 시처럼 간결하지요.

기본적인 사용법:

let 꺼낸값 = 배열이름.shift();

값을 저장하지 않고 그냥 제거만 하고 싶을 때:

배열이름.shift();

빈 배열에서 shift를 했을 때:

let 결과 = 배열이름.shift(); // undefined가 나옵니다

기억해둘 특징들:

  • shift는 항상 배열의 맨 앞에서 값을 꺼냅니다
  • 꺼낸 값을 우리에게 돌려줍니다
  • 원래 배열이 직접 변경되어 크기가 1만큼 줄어듭니다
  • 나머지 값들의 인덱스가 모두 1씩 감소합니다

🧪 실제로 사용해보기

이제 실제 예제들을 통해 shift가 어떻게 작동하는지 차근차근 살펴보겠습니다.

🔹 예제 1: 병원 대기실에서 순서대로 환자 호출하기

병원 대기실에서 대기 순서에 따라 환자를 한 명씩 호출하는 상황을 따라해보겠습니다.

// 병원 대기실에 환자분들이 순서대로 앉아 계십니다
let waitingPatients = ["김철수", "이영희", "박민수", "최지영"];

// 현재 대기 상황을 확인해봅시다
console.log("현재 대기 환자:", waitingPatients);
console.log("총 대기 인원:", waitingPatients.length);        
console.log("다음 호출 예정:", waitingPatients[0]);           

// 첫 번째 환자를 호출합니다
let currentPatient = waitingPatients.shift();

// 호출된 환자와 남은 대기열을 확인해봅시다
console.log("호출된 환자:", currentPatient);                 
console.log("남은 대기 환자:", waitingPatients);             
console.log("남은 대기 인원:", waitingPatients.length);       
console.log("다음 호출 예정:", waitingPatients[0]);           

// 한 명 더 호출해봅시다
let secondPatient = waitingPatients.shift();
console.log("두 번째 호출 환자:", secondPatient);             
console.log("이제 남은 환자:", waitingPatients);             

이 예제를 통해 shift가 실제 대기줄 시스템과 똑같이 동작한다는 것을 확인할 수 있습니다. 먼저 온 사람이 먼저 호출되고, 나머지 사람들은 자동으로 앞으로 이동하지요.

🔹 예제 2: 오늘의 할 일 목록에서 하나씩 완료하기

하루 일과에서 할 일을 하나씩 완료해나가는 과정을 상상해보겠습니다.

// 오늘 해야 할 일들을 순서대로 정리했습니다
let todayTasks = ["양치하기", "아침먹기", "숙제하기", "친구와 놀기", "저녁먹기"];

// 오늘의 할 일 목록을 확인해봅시다
console.log("오늘의 할 일:", todayTasks);
console.log("총 할 일 개수:", todayTasks.length);           

// 첫 번째 할 일을 완료합니다
let completedTask1 = todayTasks.shift();
console.log("완료한 일:", completedTask1);                  
console.log("남은 할 일:", todayTasks);                     

// 두 번째 할 일도 완료합니다
let completedTask2 = todayTasks.shift();
console.log("완료한 일:", completedTask2);                  
console.log("남은 할 일:", todayTasks);                     

// 지금까지 완료한 일들을 따로 모아볼까요?
let completedTasks = [completedTask1, completedTask2];
console.log("지금까지 완료한 일들:", completedTasks);        
console.log("다음에 할 일:", todayTasks[0]);                
console.log("아직 남은 일의 개수:", todayTasks.length);      

이 예제를 통해 shift로 꺼낸 값들을 다른 배열에 모아서 활용하는 방법과 실생활에서의 응용을 이해할 수 있습니다.

🔹 예제 3: 빈 배열 처리와 안전한 shift 사용법

배열이 비어있을 때 shift가 어떻게 동작하는지, 그리고 안전하게 사용하는 방법을 살펴보겠습니다.

// 작은 간식 바구니에 과자가 몇 개 있습니다
let snackBasket = ["쿠키", "사탕"];

// 간식 바구니 상황을 확인해봅시다
console.log("간식 바구니:", snackBasket);
console.log("간식 개수:", snackBasket.length);              

// 첫 번째 간식을 먹습니다
let snack1 = snackBasket.shift();
console.log("먹은 간식:", snack1);                         
console.log("남은 간식:", snackBasket);                    

// 두 번째 간식도 먹습니다
let snack2 = snackBasket.shift();
console.log("먹은 간식:", snack2);                         
console.log("남은 간식:", snackBasket);                    
console.log("바구니가 비었나요?", snackBasket.length === 0); 

// 이제 바구니가 비어있는데 또 간식을 꺼내려고 하면?
let snack3 = snackBasket.shift();
console.log("또 꺼낸 간식:", snack3);                       
console.log("undefined인가요?", snack3 === undefined);      

// 안전하게 간식을 꺼내는 방법
if (snackBasket.length > 0) {
    let safeSnack = snackBasket.shift();
    console.log("안전하게 꺼낸 간식:", safeSnack);
} else {
    console.log("바구니가 비어있습니다!");                     
}

이 예제를 통해 배열이 비어있을 때의 안전한 처리 방법과 undefined 결과를 이해할 수 있습니다.

🧠 주의할 점들

shift를 사용할 때 가끔 실수하는 부분들을 미리 알아두면 도움이 됩니다.

❌ 실수 1: shift와 pop 헷갈리기

첫 번째로 많이 하는 실수는 어디에서 값을 제거하고 싶은지 헷갈리는 것입니다.

let fruits = ["사과", "바나나", "오렌지"];

// ❌ 잘못된 예: 첫 번째를 제거하고 싶은데 pop을 사용
let last = fruits.pop();  // 마지막이 제거됩니다
console.log("제거된 과일:", last);     // "오렌지" (사과가 아닙니다!)
console.log("남은 과일:", fruits);     // ["사과", "바나나"]

// ✅ 올바른 예: 첫 번째를 제거하려면 shift 사용
let animals = ["강아지", "고양이", "토끼"];
let first = animals.shift();  // 첫 번째가 제거됩니다
console.log("제거된 동물:", first);    // "강아지" (첫 번째)
console.log("남은 동물:", animals);    // ["고양이", "토끼"]

❌ 실수 2: 인덱스 변화를 고려하지 않기

shift 후에 모든 값들의 인덱스가 바뀐다는 것을 잊고 원래 인덱스로 접근하려는 실수가 자주 발생합니다.

let students = ["철수", "영희", "민수"];
console.log("원래 두 번째 학생:", students[1]);  // "영희"

// ❌ 잘못된 생각: shift 후에도 영희가 여전히 1번째일 거라고 생각
students.shift(); // "철수" 제거
console.log("shift 후 1번째:", students[1]);  // "민수" (영희가 아닙니다!)

// ✅ 올바른 이해: 영희는 이제 0번째로 이동했습니다
console.log("shift 후 0번째:", students[0]);  // "영희" (여기로 이동)

❌ 실수 3: 반환값을 제대로 활용하지 않기

shift로 제거한 값을 저장하지 않아서 나중에 사용하지 못하는 실수입니다.

let colors = ["빨강", "파랑", "노랑"];

// ❌ 잘못된 사용: 제거한 값을 버립니다
colors.shift(); // 무엇이 제거되었는지 모릅니다!
console.log("남은 색깔:", colors); // ["파랑", "노랑"]
console.log("방금 뭘 제거했지?"); // 알 수 없습니다!

// ✅ 올바른 방법: 제거한 값을 저장해서 활용합니다
let numbers = [1, 2, 3];
let removedNumber = numbers.shift();
console.log("제거된 숫자:", removedNumber); // 1
console.log("남은 숫자:", numbers); // [2, 3]
console.log("제거한 값을 다시 사용:", removedNumber * 10); // 10

✏️ 연습문제로 실력 기르기

문제를 풀어보면서 shift에 대한 이해를 더욱 깊게 만들어보겠습니다.

연습문제를 풀 때마다 마치 새로운 작은 발견을 하는 것 같습니다. 코드를 한 줄씩 써보면서 예상과 결과를 비교해보는 과정에서 진정한 이해가 생겨나는 것 같습니다.

Q1. 숫자 배열에서 첫 번째 숫자를 꺼내서 출력해보세요.

여러분만의 숫자 이야기를 만들어보세요.

정답을 확인해보세요
let numbers = [10, 20, 30, 40];

console.log("처음 숫자들:", numbers);

// 첫 번째 숫자를 shift로 꺼내기
let firstNumber = numbers.shift();

console.log("꺼낸 숫자:", firstNumber);     // 10이 출력됩니다
console.log("남은 숫자들:", numbers);       // [20, 30, 40]이 출력됩니다

Q2. 동물 배열에서 동물을 두 마리 순서대로 꺼내보세요.

shift를 두 번 사용해서 차례로 동물을 꺼내보세요.

정답을 확인해보세요
let animals = ["강아지", "고양이", "토끼", "햄스터"];

console.log("처음 동물들:", animals);

// 첫 번째 동물 꺼내기
let animal1 = animals.shift();
console.log("첫 번째로 꺼낸 동물:", animal1);  // "강아지"

// 두 번째 동물 꺼내기
let animal2 = animals.shift();
console.log("두 번째로 꺼낸 동물:", animal2);  // "고양이"

console.log("남은 동물들:", animals);           // ["토끼", "햄스터"]

Q3. 빈 배열에서 shift를 시도해서 undefined가 나오는지 확인해보세요.

빈 배열에서 shift를 할 때 어떤 일이 일어나는지 직접 확인해보세요.

정답을 확인해보세요
let emptyBox = [];

console.log("빈 박스:", emptyBox);
console.log("박스가 비어있나요?", emptyBox.length === 0);  // true

// 빈 배열에서 shift 시도
let result = emptyBox.shift();

console.log("shift 결과:", result);              // undefined
console.log("undefined인가요?", result === undefined);  // true

🔄 복습하기: 지난 시간에 배운 unshift 기능

이전 단원에서 배운 unshift 기능을 간단히 복습해보겠습니다.

복습 문제: shift와 unshift를 함께 사용해서 "앞에서 빼고 앞에서 넣기" 시스템 만들기

정답을 확인해보세요
let workQueue = ["일1", "일2", "일3"]; // 일 처리 대기열

console.log("📋 일 처리 시스템 실험");

// 기존 일들 확인하기
console.log("\n기존 대기 중인 일:", workQueue);

// 긴급한 일이 생겨서 맨 앞에 추가 (unshift)
workQueue.unshift("긴급한 일");
console.log("긴급한 일 추가 후:", workQueue);

// 첫 번째 일 처리하기 (shift)
let currentWork = workQueue.shift();
console.log("현재 처리 중인 일:", currentWork);
console.log("남은 대기 일들:", workQueue);

// 또 다른 긴급한 일 추가
workQueue.unshift("또 다른 긴급한 일");
console.log("또 다른 긴급한 일 추가 후:", workQueue);

// 다음 일 처리
let nextWork = workQueue.shift();
console.log("다음 처리할 일:", nextWork);
console.log("최종 남은 일들:", workQueue);

console.log("\n🎯 결론: 긴급한 일을 우선으로 처리했습니다!");

설명: unshift로 앞에서 값을 추가하고 shift로 앞에서 값을 제거하면 "우선순위 처리" 구조가 만들어집니다. 이는 실제 응급실이나 긴급 업무 처리와 같은 원리입니다.

💪 조금 더 깊이 생각해보기

기본적인 연습을 마친 후에는 조금 더 깊이 있는 문제를 통해 shift에 대한 이해를 확인해보겠습니다.

Q1. shift와 push를 조합해서 순환하는 턴 시스템 만들어보기

정답을 확인해보세요
let players = ["철수", "영희", "민수"];

console.log("게임 시작! 플레이어:", players);

// 5턴 동안 플레이해보기
for(let turn = 1; turn <= 5; turn++) {
    let currentPlayer = players.shift(); // 현재 플레이어 뽑기
    console.log(`턴 ${turn}: ${currentPlayer}의 차례`);

    players.push(currentPlayer); // 다시 뒤에 추가 (순환)
    console.log("다음 대기줄:", players);
}

설명: shift와 push를 조합해서 플레이어들이 순환하는 턴제 게임을 만들 수 있습니다. 이는 실제 보드게임이나 카드게임에서 자주 사용하는 패턴입니다.

📚 이전 단원들과 함께 복습하기

7단원까지 공부한 내용들을 다시 떠올려보면서 shift와 함께 사용해보겠습니다.

복습 1) 함수와 배열 함께 사용하기 (5-7단원 복습)

// 배열에서 안전하게 첫 번째 값을 제거하는 함수를 만들어보세요
function safeRemoveFirst(array) {
    if(array.length > 0) {
        return array.shift();
    } else {
        return "배열이 비어있습니다";
    }
}

let testArray = ["사과", "바나나"];
console.log("제거된 값:", safeRemoveFirst(testArray)); // 이 결과는 무엇일까요?
console.log("배열 상태:", testArray);

정답: "제거된 값: 사과"와 "배열 상태: ['바나나']"가 출력됩니다.

설명: 함수에서 조건문으로 배열이 비어있지 않은지 확인한 후, 안전하게 shift로 첫 번째 값을 제거하고 돌려줍니다.

복습 2) 반복문과 조건문 함께 사용하기 (3-4단원 복습)

// while문을 사용해서 배열의 모든 값을 shift로 제거하는 코드를 작성해보세요
let todoList = ["숙제하기", "책읽기", "운동하기"];
let completedTasks = [];

while(todoList.length > 0) {
    let task = todoList.shift();
    completedTasks.push(task);
    console.log("완료한 일:", task, "/ 남은 일:", todoList);
}

console.log("모든 완료 일들:", completedTasks);

정답: 할 일들이 순서대로 완료되어 completedTasks 배열에 저장됩니다.

오늘 우리는 shift라는 기능을 통해 배열의 맨 앞에서 값을 조용히 꺼내오는 방법을 배웠습니다. 마치 줄을 서 있는 사람들 중에서 맨 앞의 사람이 자연스럽게 한 걸음 앞으로 나가는 것처럼, shift도 그런 자연스러운 방식으로 작동한다는 것을 느꼈기를 바랍니다.

이제 여러분은 push, pop, unshift, shift를 모두 자유자재로 조합해서 배열의 모든 방향을 완벽하게 조작할 수 있게 되었습니다. 마치 숙련된 교통 정리 요원이 된 것처럼, 정보들이 자연스럽게 흘러가도록 관리할 수 있는 능력을 갖추게 된 것입니다.

다음 시간에는 배열의 길이를 확인하는 방법에 대해서도 이야기해보겠습니다. 오늘도 함께 해주어서 고맙습니다.

✅ 학습 완료 체크리스트

이번 시간에 배운 내용들을 차근차근 확인해보세요.

학습 내용 확인
shift의 기본 개념 이해하기
기본 사용법과 문법 익히기
주요 특징과 차이점 알기
자주 하는 실수들 알아두기
실전 예제 이해하기
unshift와 shift 함께 사용하기

📂 마무리 정보

오늘 배운 7.2.4 내용이 여러분의 마음에 잘 자리 잡았나요? 다음 시간에도 함께 새로운 이야기를 써내려가겠습니다.

기억해둘 점: 오늘 배운 내용을 꼭 직접 써보시고, 궁금한 점이 있으면 언제든 다시 돌아와서 천천히 읽어보세요.


🚀 더 체계적인 JavaScript 학습을 원하신다면?
이 포스팅에서 다룬 내용을 실제로 실습해보세요!
무료 JavaScript 학습 플랫폼에서 단계별 학습과 실시간 코드 실행을 통해
더욱 효과적이고 재미있게 학습하실 수 있습니다.
📝 실시간 코드 실행 📊 학습 진도 관리 👥 체계적 커리큘럼
📚 171개 체계적 학습레슨 · 📋 855개 4지선다 연습문제 · 🆓 완전 무료 · ⚡ 즉시 시작