📘 16.1.1 프로토타입이라는 특별한 시스템 - 자바스크립트의 독특한 가족 연결 방식
어느 조용한 저녁, 창밖으로 스며드는 노을빛을 바라보며 생각해봅니다. 여러분이 클래스로 물건을 만드는 방법을 차근차근 배웠던 그 시간들 말이에요. 그런데 자바스크립트에는 클래스가 생기기 훨씬 전부터 사용해온 더 오래되고 독특한 방법이 있어요. 바로 프로토타입(prototype)이라는 신비로운 시스템이지요.
프로토타입은 마치 우리 가족의 DNA처럼 부모에서 자녀로 특별한 능력이 자연스럽게 전해지는 방식이에요. 할머니가 요리를 잘하면 엄마도, 그래서 여러분도 요리를 잘할 수 있게 되는 것처럼요. 오늘은 자바스크립트의 심장 깊숙이 조용히 숨어있는 이 프로토타입의 놀라운 비밀을 함께 탐험해보겠습니다.
🧠 새로운 단어들과 친해지기
프로토타입이라는 독특한 시스템을 이해하기 위해 꼭 알아야 할 새로운 단어들을 먼저 살펴볼까요?
단어 | 쉬운 설명 |
---|---|
프로토타입 | 자바스크립트에서 물건이 다른 물건으로부터 특별한 능력을 물려받는 독특한 방식이에요. 마치 가족의 DNA 같아요. |
물려받기 | 한 물건이 다른 물건의 특별한 능력이나 정보를 받아서 사용할 수 있게 되는 것이에요. |
프로토타입 사슬 | 물건이 능력을 찾을 때 자신의 조상들을 따라 올라가는 연결된 길이에요. 가족 족보 같아요. |
생성자 함수 | new 키워드와 함께 사용해서 물건을 만드는 특별한 함수예요. |
프로토타입은 그리스어로 "원본"이라는 뜻이에요. 마치 공장에서 제품을 만들 때 사용하는 원본 틀처럼, 모든 물건이 조용히 참고하는 기본 모델인 거예요.
✨ 프로토타입 시스템이 뭔지 알아보기
프로토타입은 자바스크립트만의 독특하고 강력한 가족 시스템이에요. 다른 프로그래밍 언어들이 클래스를 중심으로 하는 가족 만들기를 사용하는 것과 달리, 자바스크립트는 물건이 직접 다른 물건을 따라가는 방식으로 가족을 만들어요.
자바스크립트의 모든 물건은 숨겨진 프로토타입이라는 가족 연결고리를 가지고 있어요. 물건에서 어떤 특별한 능력이나 정보를 찾을 때, 그 물건에 직접 없다면 자동으로 조상(프로토타입)을 확인하러 조용히 가요. 조상에도 없다면 조상의 조상을 차분히 확인하고, 이런 식으로 계속 올라가면서 찾아요.
이런 구조 덕분에 여러 물건이 같은 능력을 함께 나눠 쓸 수 있어서 컴퓨터 메모리를 절약하고, 나중에 조상을 바꾸면 모든 후손들에게 즉시 반영되는 놀라운 유연성을 제공해요.
재미있는 비유: 우리 가족의 특별한 능력 전수
프로토타입을 '우리 가족의 특별한 능력 전수'에 비유해서 이해해볼까요?
여러분의 가족에는 대대로 내려오는 특별한 능력들이 있을 거예요. 할머니가 하시던 특별한 김치찌개 만들기, 할아버지가 가르쳐주신 정중한 인사법, 가족만의 독특한 재미있는 놀이들 말이에요.
우리 가족의 능력 전수:
- 할머니: "김치찌개 끓이는 법", "예의 바른 인사하는 법"
- 엄마: 할머니의 모든 능력을 물려받음 + "컴퓨터 사용하는 법" 추가
- 여러분: 엄마의 모든 능력을 물려받음 + "게임 잘하는 법" 추가
여러분이 뭔가 필요할 때는 이런 순서로 찾아보죠:
- 먼저 내가 아는지 확인해봐요
- 모르면 엄마에게 물어봐요
- 엄마도 모르면 할머니에게 물어봐요
- 계속 조상들을 따라 올라가면서 찾아요
프로토타입도 똑같아요! 물건이 어떤 특별한 능력이나 정보를 찾을 때 가족의 능력을 찾아가는 것처럼 프로토타입 사슬을 따라 올라가면서 찾는 거예요.
🎯 왜 프로토타입 시스템을 배워야 할까요?
"그런데 선생님, 클래스도 있는데 왜 굳이 이 어려운 프로토타입을 배워야 하나요?" 이런 궁금증이 생길 수 있어요. 프로토타입을 배우는 이유는 정말 중요해요!
첫 번째로 자바스크립트의 진짜 작동 원리를 알 수 있어요. 우리가 사용하는 배열의 push()
, 문자열의 split()
같은 멋진 기능들이 모두 프로토타입에서 오는 거거든요. 심지어 클래스도 사실은 프로토타입을 좀 더 쉽게 사용할 수 있게 만든 예쁜 포장지일 뿐이에요.
두 번째로 컴퓨터 메모리를 똑똑하게 사용할 수 있어요. 수천 개의 물건을 만들 때, 각 물건마다 똑같은 기능을 복사하는 대신 조상에 한 번만 만들어두면 모든 후손이 함께 사용할 수 있어요. 정말 경제적이죠!
세 번째로 매우 유연한 프로그래밍이 가능해져요. 프로토타입은 프로그램이 실행되는 중에도 바꿀 수 있어서, 실시간으로 물건의 동작을 바꿀 수 있어요. 이런 특성이 자바스크립트를 매우 강력하게 만들어줘요.
네 번째로 다른 사람들과 대화할 때 도움이 돼요. 프로그래밍에서 일하는 사람들과 이야기할 때 프로토타입을 이해하지 못하면 대화가 어려워질 수 있어요.
⚙️ 프로토타입 시스템 사용법 배우기
프로토타입을 사용하는 기본적인 방법은 생성자 함수와 함께 사용하는 거예요.
물건 만들기 함수 정의:
function 물건만들기함수이름(필요한정보들) {
this.특징1 = 값1;
this.특징2 = 값2;
}
조상에게 공통 능력 추가:
물건만들기함수이름.prototype.능력이름 = function() {
// 능력의 내용
};
물건 생성하고 사용:
let 새물건 = new 물건만들기함수이름(필요한정보들);
새물건.능력이름(); // 조상의 능력 사용하기
간단한 예시:
// 강아지 만들기 함수 정의
function Dog(name) {
this.name = name; // 각 강아지의 이름
}
// 모든 강아지가 사용할 공통 능력을 조상에게 추가
Dog.prototype.bark = function() {
return this.name + "이(가) 멍멍!";
};
// 강아지 만들기
let myDog = new Dog("바둑이");
console.log(myDog.bark()); // "바둑이이(가) 멍멍!"
🧪 직접 해보면서 배우기
이제 실제 예시를 통해서 프로토타입이 어떻게 동작하는지 자세히 살펴볼게요.
🔹 첫 번째 예시: 여러 물건이 같은 능력 나눠 쓰기
첫 번째로는 여러 물건이 어떻게 같은 능력을 조상을 통해서 나눠 쓰는지 확인해볼게요.
// 동물 만들기 함수 정의
function Animal(name, species) {
this.name = name; // 각 동물의 이름 (개별 특징)
this.species = species; // 각 동물의 종류 (개별 특징)
}
// 모든 동물이 나눠 쓸 능력을 조상에게 추가
Animal.prototype.introduce = function() {
return "안녕! 나는 " + this.species + " " + this.name + "이야!";
};
Animal.prototype.eat = function(food) {
return this.name + "이(가) " + food + "를 맛있게 먹고 있어요.";
};
Animal.prototype.sleep = function() {
return this.name + "이(가) 꿀잠을 자고 있어요. 💤";
};
// 여러 동물 만들기
let 강아지 = new Animal("멍멍이", "강아지");
let 고양이 = new Animal("야옹이", "고양이");
let 앵무새 = new Animal("짹짹이", "앵무새");
// 모든 동물이 같은 능력을 사용할 수 있어요
console.log(강아지.introduce()); // "안녕! 나는 강아지 멍멍이야!"
console.log(고양이.introduce()); // "안녕! 나는 고양이 야옹이야!"
console.log(앵무새.eat("씨앗")); // "짹짹이이(가) 씨앗를 맛있게 먹고 있어요."
console.log(강아지.sleep()); // "멍멍이이(가) 꿀잠을 자고 있어요. 💤"
// 신기한 사실: 능력은 각 동물에 복사되지 않고 조상에서 함께 사용돼요
console.log("강아지와 고양이가 같은 introduce 능력을 쓰나요?", 강아지.introduce === 고양이.introduce); // true (같은 함수를 가리켜요)
// 각 동물은 자신만의 특징을 가져요
console.log("강아지와 고양이가 같은 동물인가요?", 강아지 === 고양이); // false (서로 다른 동물이에요)
이 과정을 차근차근 살펴보면, 생성자 함수로 각 동물의 개별 특징을 설정하고, 조상(프로토타입)에 공통 능력을 정의해요. 만들어진 모든 동물들은 자신만의 이름과 종류를 가지지만, 능력은 조상에서 함께 나눠 써요.
🔹 두 번째 예시: 물건이 능력을 찾아가는 탐험 여행
두 번째로는 물건이 능력을 찾는 과정, 즉 프로토타입 사슬이 어떻게 작동하는지 알아볼게요.
// 학생 만들기 함수
function Student(name, grade) {
this.name = name; // 학생 이름
this.grade = grade; // 학년
}
// 조상에게 공통 능력 추가
Student.prototype.study = function(subject) {
return this.name + "이(가) " + subject + "를 열심히 공부합니다.";
};
Student.prototype.getInfo = function() {
return this.name + "는 " + this.grade + "학년입니다.";
};
Student.prototype.playGame = function(game) {
return this.name + "이(가) " + game + "를 재미있게 하고 있어요!";
};
// 학생 만들기
let 철수 = new Student("철수", 4);
// 1단계: 물건 자체에서 찾기
console.log("철수의 이름:", 철수.name); // "철수" (철수 자신에게서 찾음)
console.log("철수의 학년:", 철수.grade); // 4 (철수 자신에게서 찾음)
// 2단계: 조상(프로토타입)에서 찾기
console.log(철수.study("수학")); // 조상에서 study 능력을 찾아서 실행
console.log(철수.getInfo()); // 조상에서 getInfo 능력을 찾아서 실행
console.log(철수.playGame("축구")); // 조상에서 playGame 능력을 찾아서 실행
// 능력이 어디서 왔는지 확인해보기
console.log("name이 철수 자신에게 있나요?", 철수.name !== undefined); // true
console.log("study가 철수 자신에게 있나요?", 철수.study === Student.prototype.study); // true (조상에서 가져온 거예요)
// 조상 확인하기 - 간단한 방법
console.log("철수의 조상은 Student.prototype인가요?", 철수.__proto__ === Student.prototype); // true
이 예시에서는 물건이 특징이나 능력을 찾는 순서를 보여줘요. 먼저 자기 자신에서 찾고, 없으면 조상으로 올라가면서 찾는 탐험 과정이죠.
🔹 세 번째 예시: 실시간으로 조상 바꾸기
세 번째로는 프로토타입의 강력한 특징 중 하나인 실시간 바꾸기를 확인해볼게요.
// 자동차 만들기 함수
function Car(brand, model) {
this.brand = brand; // 브랜드
this.model = model; // 모델
this.speed = 0; // 현재 속도 (처음엔 0)
}
// 기본 능력 추가
Car.prototype.accelerate = function() {
this.speed = this.speed + 10; // 속도를 10씩 높이기
return this.brand + " " + this.model + "이(가) 가속합니다! 현재 속도: " + this.speed + "km/h";
};
Car.prototype.brake = function() {
if (this.speed - 15 < 0) {
this.speed = 0; // 속도가 0 아래로 내려가지 않게 하기
} else {
this.speed = this.speed - 15; // 속도를 15씩 줄이기
}
return this.brand + " " + this.model + "이(가) 브레이크를 밟습니다. 현재 속도: " + this.speed + "km/h";
};
// 자동차들 만들기
let 내차 = new Car("현대", "소나타");
let 친구차 = new Car("기아", "K5");
// 기존 능력 사용하기
console.log(내차.accelerate()); // "현대 소나타이(가) 가속합니다! 현재 속도: 10km/h"
console.log(친구차.brake()); // "기아 K5이(가) 브레이크를 밟습니다. 현재 속도: 0km/h"
// 🌟 프로그램이 실행되는 중에 새로운 능력 추가하기!
Car.prototype.honk = function() {
return this.brand + " " + this.model + ": 빵빵! 🚗";
};
Car.prototype.turnOnMusic = function() {
return this.brand + " " + this.model + "에서 신나는 음악이 나와요! 🎵";
};
// 이미 만들어진 자동차들도 새 능력을 바로 사용할 수 있어요!
console.log(내차.honk()); // "현대 소나타: 빵빵! 🚗"
console.log(친구차.turnOnMusic()); // "기아 K5에서 신나는 음악이 나와요! 🎵"
// 기존 능력도 바꿀 수 있어요
Car.prototype.accelerate = function() {
this.speed = this.speed + 20; // 더 빠르게 변경!
return this.brand + " " + this.model + "이(가) 슈퍼 가속! 속도: " + this.speed + "km/h 🚀";
};
console.log(친구차.accelerate()); // "기아 K5이(가) 슈퍼 가속! 속도: 20km/h 🚀"
// 모든 자동차가 바뀐 능력을 사용해요
console.log(내차.accelerate()); // "현대 소나타이(가) 슈퍼 가속! 속도: 30km/h 🚀"
이 예시의 핵심은 조상(프로토타입)을 나중에 바꿔도 이미 만들어진 모든 후손들에게 즉시 반영된다는 점이에요. 이런 특성이 자바스크립트를 매우 유연하게 만들어줘요.
🔄 프로토타입 시스템 사용 과정 정리하기
지금까지 학습한 프로토타입 시스템 사용 과정을 자연스럽게 정리해볼게요.
첫 번째 단계는 물건 만들기 함수 정의하기예요. 물건이 가질 개별적인 특징들을 this.특징명
형태로 설정하는 거죠.
두 번째 단계는 조상에게 공통 능력 추가하기예요. 물건만들기함수.prototype.능력명
형태로 모든 후손이 함께 사용할 능력을 정의해요.
세 번째 단계는 물건 만들기예요. new
키워드를 사용해서 생성자 함수로부터 새로운 물건을 만드는 과정이에요.
네 번째 단계는 능력 사용하기예요. 만들어진 물건에서 능력을 사용하면 프로토타입 사슬을 따라 능력을 찾아서 실행해요.
마지막 단계는 실시간으로 바꾸기예요. 필요에 따라 조상에게 새로운 능력을 추가하거나 기존 능력을 바꿀 수 있어요.
🧚♀️ 이야기로 다시 배우기: 학교의 특별한 도서관
지금까지 배운 내용을 따뜻한 이야기로 다시 정리해볼까요?
어느 학교에 정말 신기한 도서관이 하나 있었어요. 이 도서관에는 아주 특별한 규칙이 있었답니다.
각 학생들은 개인 서재를 하나씩 가지고 있었어요. 하지만 모든 책을 개인 서재에 보관하기에는 공간이 부족했죠. 그래서 도서관에는 공용 서고 시스템이 있었어요.
학교 도서관의 체계적인 시스템:
- 개인 서재: 각 학생만의 개인적인 노트와 교재
- 2층 전문 서고: 특정 학년 학생들이 함께 사용하는 전문 교재
- 1층 공용 서고: 모든 학생이 공통으로 사용하는 기본 교재
학생이 어떤 책을 찾을 때는 이런 체계적인 순서로 찾아봤어요:
- 먼저 자신의 개인 서재에서 찾기
- 없으면 2층 전문 서고에서 찾기
- 그래도 없으면 1층 공용 서고에서 찾기
- 마지막까지 없으면 "그런 책은 없다"고 결론
더욱 신기한 건 사서 선생님이 새로운 책을 공용 서고에 추가하면, 모든 학생이 바로 그 책을 사용할 수 있었다는 거예요! 심지어 이미 도서관에 있던 학생들도 즉시 새로운 지식을 배울 수 있게 되었답니다.
어느 날, 사서 선생님이 1층 공용 서고에 "코딩 기초 교재"를 새로 추가했어요. 그러자 어떤 일이 일어났을까요? 도서관에 있던 모든 학생들이 갑자기 코딩을 배울 수 있게 되었어요!
"와! 이 책은 언제 들어왔지?" 학생들이 놀라워했지만, 이것이 바로 학교 도서관의 특별한 시스템이었답니다.
프로토타입도 똑같은 체계적인 도서관이에요! 개인 서재가 물건 자신의 특징이고, 공용 서고가 프로토타입인 거죠. 찾는 순서도 똑같고, 나중에 조상(프로토타입)에 추가한 능력도 모든 후손이 바로 사용할 수 있어요!
🧠 자주 하는 실수와 주의할 점
프로토타입 시스템을 사용할 때 초보자들이 자주 하는 실수들을 미리 알아두면 더 완벽한 코딩을 할 수 있어요.
❌ 실수 1: 개별 물건에 prototype을 사용하려고 시도하기
// 동물 만들기 함수
function Animal(name) {
this.name = name;
}
let 강아지 = new Animal("멍멍이");
// 이렇게 하면 안 돼요! - 개별 물건에 prototype 사용하려고 함
// 강아지.prototype.bark = function() { ... }; // 에러가 나요!
// 올바른 방법 - 생성자 함수의 prototype 사용
Animal.prototype.bark = function() {
return this.name + "이(가) 멍멍!";
};
console.log(강아지.bark()); // 정상 작동해요!
// 왜 그럴까요?
console.log("강아지에게 prototype이 있나요?", 강아지.prototype); // undefined (없어요!)
console.log("Animal에게 prototype이 있나요?", Animal.prototype); // {} (있어요!)
prototype
은 생성자 함수의 특별한 속성이지, 개별 물건의 속성이 아니에요. 개별 물건에는 prototype
속성이 없어요.
❌ 실수 2: 조상을 통째로 바꿔버리기
function Person(name) {
this.name = name;
}
// 이미 만들어진 사람
let 철수 = new Person("철수");
// 이렇게 하면 위험해요! - 조상을 완전히 바꿔버리기
Person.prototype = {
greet: function() {
return "안녕, " + this.name + "!";
}
};
// 철수는 새로운 능력을 사용할 수 없어요!
// console.log(철수.greet()); // 에러가 나요!
// 새로 만든 사람은 사용할 수 있어요
let 영희 = new Person("영희");
console.log(영희.greet()); // "안녕, 영희!" (정상 작동)
// 올바른 방법 - 조상에게 능력 추가하기
Person.prototype.introduce = function() {
return "제 이름은 " + this.name + "입니다.";
};
// 이제 철수도 사용할 수 있어요!
console.log(철수.introduce()); // "제 이름은 철수입니다." (정상 작동)
console.log(영희.introduce()); // "제 이름은 영희입니다." (정상 작동)
조상을 완전히 바꿔버리면 이미 만들어진 물건들이 새로운 조상과 연결이 끊어져요. 능력을 추가할 때는 바꾸지 말고 기존 조상에 추가하세요.
❌ 실수 3: 조상에게 배열이나 객체를 직접 주기
function Student(name) {
this.name = name;
}
// 위험한 방법 - 모든 학생이 같은 배열을 함께 사용해요!
Student.prototype.subjects = [];
let 철수 = new Student("철수");
let 영희 = new Student("영희");
철수.subjects.push("수학"); // 철수가 수학을 추가했는데...
console.log(영희.subjects); // ["수학"] - 영희에게도 수학이 들어있어요!
// 왜 이런 일이 일어날까요?
console.log("같은 배열을 사용하나요?", 철수.subjects === 영희.subjects); // true (같은 배열이에요!)
// 올바른 방법 - 생성자에서 개별 배열 만들기
function SafeStudent(name) {
this.name = name;
this.subjects = []; // 각 학생마다 새로운 배열
}
SafeStudent.prototype.addSubject = function(subject) {
this.subjects.push(subject);
return this.name + "이(가) " + subject + " 과목을 추가했어요!";
};
SafeStudent.prototype.getSubjects = function() {
let result = this.name + "의 과목들: ";
for (let i = 0; i < this.subjects.length; i++) {
if (i > 0) result = result + ", ";
result = result + this.subjects[i];
}
return result;
};
// 안전한 방법으로 테스트
let 안전한철수 = new SafeStudent("철수");
let 안전한영희 = new SafeStudent("영희");
console.log(안전한철수.addSubject("수학")); // "철수이(가) 수학 과목을 추가했어요!"
console.log(안전한영희.addSubject("과학")); // "영희이(가) 과학 과목을 추가했어요!"
console.log(안전한철수.getSubjects()); // "철수의 과목들: 수학"
console.log(안전한영희.getSubjects()); // "영희의 과목들: 과학"
조상에게 배열이나 객체를 직접 주면 모든 후손이 같은 배열을 함께 사용하게 되어서 예상치 못한 문제가 생길 수 있어요.
✏️ 직접 해보기 - 쉬운 연습 문제들
고요한 시간이 흐른 지금, 배운 내용을 연습 문제를 통해서 차분히 익혀볼게요.
Ex1) 책 만들기와 조상 능력 추가하기 - "내 도서관 만들기 프로젝트"
// 책 만들기 함수 (제목과 저자를 받아요)
function Book(title, author) {
this.title = title; // 책 제목
this.author = author; // 저자
this.isRead = false; // 읽었는지 여부 (처음엔 안 읽음)
}
// 조상에게 공통 능력 추가하기
Book.prototype.read = function() {
this.isRead = true; // 읽음 상태로 바꾸기
return "'" + this.title + "'을(를) 다 읽었어요! 정말 재미있었어요! 📖";
};
Book.prototype.getInfo = function() {
let status = this.isRead ? "✅ 읽음" : "📚 안 읽음"; // 읽었는지 확인
return "📖 " + this.title + " - " + this.author + " (" + status + ")";
};
Book.prototype.recommend = function() {
if (this.isRead) {
return this.title + "는 정말 좋은 책이에요! 꼭 읽어보세요! ⭐";
} else {
return this.title + "를 아직 안 읽어봤어요. 읽고 나서 추천해드릴게요!";
}
};
// 책들 만들고 사용해보기
let 해리포터 = new Book("해리포터와 마법사의 돌", "J.K. 롤링");
let 어린왕자 = new Book("어린왕자", "생텍쥐페리");
let 파브르곤충기 = new Book("파브르 곤충기", "파브르");
console.log(해리포터.getInfo()); // "📖 해리포터와 마법사의 돌 - J.K. 롤링 (📚 안 읽음)"
console.log(해리포터.read()); // "'해리포터와 마법사의 돌'을(를) 다 읽었어요! 정말 재미있었어요! 📖"
console.log(해리포터.getInfo()); // "📖 해리포터와 마법사의 돌 - J.K. 롤링 (✅ 읽음)"
console.log(해리포터.recommend()); // "해리포터와 마법사의 돌는 정말 좋은 책이에요! 꼭 읽어보세요! ⭐"
console.log(어린왕자.recommend()); // "어린왕자를 아직 안 읽어봤어요. 읽고 나서 추천해드릴게요!"
Ex2) 계산기 만들기 프로젝트 - "나만의 똑똑한 계산기"
어느 조용한 오후, 우리는 계산기를 만드는 이야기를 통해 프로토타입을 연습해보겠습니다.
// 계산기 만들기 함수
function Calculator(name) {
this.name = name; // 계산기 이름
this.result = 0; // 계산 결과 (처음엔 0)
this.history = []; // 계산 기록 저장소
}
// 조상에게 계산 능력들 추가하기
Calculator.prototype.add = function(number) {
this.result = this.result + number; // 숫자 더하기
this.history.push("+ " + number + " = " + this.result); // 기록 저장
return this; // 연속으로 계산할 수 있게 자기 자신을 돌려줘요
};
Calculator.prototype.subtract = function(number) {
this.result = this.result - number; // 숫자 빼기
this.history.push("- " + number + " = " + this.result); // 기록 저장
return this; // 연속 계산을 위해 자기 자신 돌려주기
};
Calculator.prototype.multiply = function(number) {
this.result = this.result * number; // 숫자 곱하기
this.history.push("× " + number + " = " + this.result); // 기록 저장
return this; // 연속 계산을 위해 자기 자신 돌려주기
};
Calculator.prototype.divide = function(number) {
if (number === 0) {
return "0으로 나눌 수 없어요! 😅"; // 0으로 나누기 방지
}
this.result = this.result / number; // 숫자 나누기
this.history.push("÷ " + number + " = " + this.result); // 기록 저장
return this; // 연속 계산을 위해 자기 자신 돌려주기
};
Calculator.prototype.getResult = function() {
return this.name + " 최종 결과: " + this.result + " 🎯";
};
Calculator.prototype.showHistory = function() {
let historyText = this.name + " 계산 기록:\n";
for (let i = 0; i < this.history.length; i++) {
historyText = historyText + this.history[i] + "\n";
}
historyText = historyText + "📝";
return historyText;
};
Calculator.prototype.clear = function() {
this.result = 0; // 결과 초기화
this.history = []; // 기록 초기화
return this.name + "를 깨끗하게 초기화했어요! ✨";
};
// 계산기 사용해보기
let 내계산기 = new Calculator("똑똑한 계산기");
// 연속으로 계산하기 (메서드 체이닝)
내계산기.add(10).subtract(3).multiply(2).add(5);
console.log(내계산기.getResult()); // "똑똑한 계산기 최종 결과: 19 🎯"
console.log(내계산기.showHistory());
// "똑똑한 계산기 계산 기록:
// + 10 = 10
// - 3 = 7
// × 2 = 14
// + 5 = 19
// 📝"
// 다른 계산기도 만들어보기
let 친구계산기 = new Calculator("친구 계산기");
친구계산기.add(100).divide(4);
console.log(친구계산기.getResult()); // "친구 계산기 최종 결과: 25 🎯"
🤔 조금 더 어려운 문제로 실력 확인하기
기본 연습을 마쳤다면, 이제 조금 더 깊이 있는 문제들을 통해서 프로토타입에 대한 이해를 확인해볼게요.
Q1. 프로토타입과 클래스의 주요 차이점은 무엇인가요?
정답: 프로토타입은 자바스크립트의 원래 방식으로 프로그램이 실행되는 중에도 자유자재로 바꿀 수 있고, 물건끼리 직접적인 연결을 통해 능력을 물려받아요. 클래스는 나중에 나온 더 쉬운 방법으로 프로토타입을 더 예쁘게 포장한 거예요. 하지만 내부적으로는 여전히 프로토타입을 사용해요. 프로토타입은 더 자유롭지만 복잡하고, 클래스는 더 구조적이고 이해하기 쉬워요.
Q2. 다음 코드의 결과와 그 이유를 설명해보세요.
function Person() {}
Person.prototype.age = 25;
let 철수 = new Person();
let 영희 = new Person();
Person.prototype.age = 30;
console.log(철수.age);
console.log(영희.age);
정답: 둘 다 30
이 나와요. 철수와 영희는 모두 Person.prototype을 조상으로 가지고 있기 때문에, 나중에 조상의 age를 바꾸면 모든 후손에서 바뀐 값을 보게 돼요. 이것이 프로토타입의 실시간 반영 특성이에요.
📚 복습 문제 - 이전에 배운 내용 기억하기
이제 이전 단원에서 배운 중요한 내용들을 복습해보며 기억을 새롭게 해볼게요!
🔄 복습 1: 클래스 기본 개념 (15단원 복습)
// 문제: 다음 코드에서 빈 칸을 채워 Animal 클래스를 완성해보세요.
______ Animal { // 빈 칸 1: 클래스 선언 키워드
_______(name, species) { // 빈 칸 2: 생성자 메서드 이름
this.name = name;
this.species = species;
this.energy = 100;
}
eat() {
if (this.energy + 20 > 100) {
this.energy = 100;
} else {
this.energy = this.energy + 20;
}
console.log(this.name + "이(가) 먹이를 먹었어요! 에너지: " + this.energy);
}
sleep() {
this.energy = 100;
console.log(this.name + "이(가) 잠을 자고 완전히 회복되었어요!");
}
}
// 동물 만들고 테스트하기
let myPet = _____ Animal("멍멍이", "강아지"); // 빈 칸 3: 객체 생성 키워드
myPet.eat();
myPet.sleep();
정답:
class Animal { // 빈 칸 1: class
constructor(name, species) { // 빈 칸 2: constructor
this.name = name;
this.species = species;
this.energy = 100;
}
eat() {
if (this.energy + 20 > 100) {
this.energy = 100;
} else {
this.energy = this.energy + 20;
}
console.log(this.name + "이(가) 먹이를 먹었어요! 에너지: " + this.energy);
}
sleep() {
this.energy = 100;
console.log(this.name + "이(가) 잠을 자고 완전히 회복되었어요!");
}
}
let myPet = new Animal("멍멍이", "강아지"); // 빈 칸 3: new
해설: 클래스를 선언할 때는 class
키워드를 사용하고, 생성자는 constructor
메서드로 정의하며, 객체를 만들 때는 new
키워드를 사용합니다.
🔄 복습 2: 상속과 super 키워드 (15.3단원 복습)
// 문제: 다음 상속 코드의 실행 결과를 예측해보세요.
class Vehicle {
constructor(brand) {
this.brand = brand;
this.speed = 0;
}
start() {
console.log(this.brand + " 시동을 걸었어요.");
}
accelerate() {
this.speed = this.speed + 10;
console.log("속도: " + this.speed + "km/h");
}
}
class Car extends Vehicle {
constructor(brand, color) {
super(brand); // 부모 생성자 호출
this.color = color;
}
start() {
super.start(); // 부모 메서드 호출
console.log(this.color + "색 자동차가 준비되었어요!");
}
}
let myCar = new Car("현대", "빨간");
myCar.start();
myCar.accelerate();
정답:
현대 시동을 걸었어요.
빨간색 자동차가 준비되었어요!
속도: 10km/h
해설: super(brand)
로 부모 생성자를 호출하여 brand 속성을 설정하고, super.start()
로 부모의 start 메서드를 호출한 후 자식만의 추가 기능을 실행합니다. accelerate 메서드는 오버라이딩하지 않았으므로 부모의 메서드가 그대로 실행됩니다.
지금까지 프로토타입이라는 독특한 시스템에 대해 자세히 알아봤어요. 프로토타입은 자바스크립트의 심장과 같은 중요한 개념이에요. 처음에는 어려울 수 있지만, 한 번 이해하고 나면 자바스크립트가 어떻게 동작하는지 훨씬 명확하게 보일 거예요! 마치 학교 도서관의 체계적인 시스템을 알게 된 것처럼, 이제 여러분은 자바스크립트의 깊은 원리를 이해하는 진짜 개발자가 되었답니다! 👨💻✨
✅ 학습 완료 체크리스트
이번 시간에 배운 내용들을 모두 이해했는지 확인해보세요!
학습 내용 | 이해했나요? |
---|---|
프로토타입의 기본 개념 | ✅ |
생성자 함수와 prototype 속성 | ✅ |
프로토타입 사슬의 동작 원리 | ✅ |
자주 하는 실수들과 해결법 | ✅ |
실전 예제 이해 | ✅ |
📂 마무리 정보
오늘 배운 16.1.1
내용이 여러분의 자바스크립트 지식 상자에 잘 저장되었나요? 다음 시간에는 더 재미있는 내용으로 만나요!
기억할 점: 프로토타입은 자바스크립트의 핵심 원리예요. 꼭 연습해보시고, 궁금한 점이 있으면 언제든 다시 돌아와서 읽어보세요.
무료 JavaScript 학습 플랫폼에서 단계별 학습과 실시간 코드 실행을 통해
더욱 효과적이고 재미있게 학습하실 수 있습니다.
'16. 프로토타입과 상속의 비밀 > 16.1 prototype 개념' 카테고리의 다른 글
16.1.3 `__proto__`와 `prototype` - 두 친구의 다른 역할 (0) | 2025.07.24 |
---|---|
16.1.2 프로토타입 체인 - 가족처럼 이어진 특별한 연결고리 (0) | 2025.07.23 |