📘 16.2.2 프로토타입으로 메서드 추가하기 - 모두가 함께 쓰는 공통 기능
어떤 이야기든 반복되는 것들이 있습니다. 매일 아침 일어나서 이를 닦고, 밥을 먹고, 학교에 가는 일상의 반복처럼요. 코딩에서도 이런 반복되는 일들이 있어요. 그런데 같은 일을 여러 번 만들어두는 것보다는, 한 번만 만들어서 모두가 함께 사용한다면 얼마나 좋을까요?
오늘은 그런 이야기를 해보려고 해요. 모든 객체가 함께 사용할 수 있는 공통 기능을 만드는 방법. 마치 우리 동네 작은 도서관에 있는 책 한 권을 모든 사람이 돌아가며 읽는 것처럼, 컴퓨터 안에서도 그런 나눔이 가능하답니다.
🧠 새로운 단어들과 친해지기
단어 | 쉬운 설명 |
---|---|
프로토타입 메서드 | 모든 객체가 함께 사용할 수 있는 공통 기능 |
인스턴스 메서드 | 각 객체가 개별적으로 가지는 기능 |
메모리 절약 | 같은 기능을 여러 번 만들지 않아서 컴퓨터 메모리를 아끼는 것 |
프로토타입 메서드는 영어로 "Prototype Method"예요. "Prototype"은 "원형", "기본 틀"이라는 뜻이고, "Method"는 "방법", "기능"이라는 뜻이에요. 즉, 기본 틀에 들어있는 공통 기능이라는 의미랍니다.
✨ 프로토타입 메서드가 뭐예요?
프로토타입 메서드는 모든 객체가 공유해서 사용하는 기능이에요. 마치 우리 집 냉장고에 붙어있는 자석 메모판처럼, 가족 모두가 필요할 때마다 그곳에 메모를 적고 확인하는 것과 비슷해요.
각자의 방에 메모판을 하나씩 둘 필요 없이, 냉장고 하나에만 두고 모두가 함께 사용하는 거죠.
현실 속 이야기: 동네 도서관의 작은 기적
우리 동네에는 작은 도서관이 하나 있어요. 그곳에는 참고서 코너가 따로 있죠. 영어사전, 국어사전, 백과사전... 이런 책들은 대출이 되지 않아요. 하지만 누구나 와서 필요할 때 찾아볼 수 있어서 정말 좋아요.
만약 동네 아이들이 각자 집에 백과사전을 사야 한다면 얼마나 비쌀까요? 하지만 도서관에 하나만 있어도 모든 아이들이 숙제할 때 필요한 정보를 찾을 수 있어요.
- 동네 아이들 = 생성자 함수로 만든 객체들
- 각자의 이름과 학년 = 각 객체가 가진 고유 속성
- 도서관의 참고서 = 프로토타입 메서드
- 사전 찾아보기 = 메서드 호출
이렇게 하면 새로운 참고서가 들어와도 도서관에 한 권만 비치하면 모든 아이들이 바로 이용할 수 있어요. 참 효율적이죠?
🎯 왜 프로토타입 메서드를 사용할까요?
1. 메모리를 아껴써요
같은 기능을 100번 복사하는 대신, 한 번만 만들어서 모두가 사용해요. 마치 학교 급식실에 밥솥 하나로 모든 학생이 밥을 먹는 것처럼요.
2. 관리하기 쉬워요
기능을 수정할 때 한 곳만 바꾸면 모든 객체에 바로 적용돼요. 학교 방송실에서 알림 한 번만 방송하면 모든 교실에 전달되는 것과 같아요.
3. 나중에 기능을 추가하기 쉬워요
이미 만들어진 객체들도 새로운 기능을 바로 사용할 수 있어요.
4. 코드가 더 깔끔해져요
비슷한 코드를 여러 번 쓸 필요가 없어서 코드가 더 읽기 쉬워요.
⚙️ 기본 사용법
프로토타입에 메서드 추가하기:
// 1단계: 생성자 함수 만들기
function Student(name, grade) {
this.name = name;
this.grade = grade;
}
// 2단계: 프로토타입에 메서드 추가하기
Student.prototype.introduce = function() {
return "안녕하세요! " + this.grade + "학년 " + this.name + "이에요";
};
Student.prototype.study = function(subject) {
return this.name + "이(가) " + subject + "를 열심히 공부해요";
};
// 3단계: 객체 만들고 사용하기
let student1 = new Student("민지", 3);
let student2 = new Student("철수", 4);
console.log(student1.introduce()); // "안녕하세요! 3학년 민지이에요"
console.log(student2.study("수학")); // "철수이(가) 수학를 열심히 공부해요"
🧪 실제 예제로 연습하기
🔹 강아지 보육원 만들기
// 강아지 생성자 함수
function Dog(name, breed, age) {
this.name = name;
this.breed = breed;
this.age = age;
this.energy = 100;
this.happiness = 50;
}
// 프로토타입에 짖는 기능 추가
Dog.prototype.bark = function() {
this.energy -= 5;
return this.name + "이(가) 멍멍! 짖어요 (에너지: " + this.energy + ")";
};
// 프로토타입에 소개 기능 추가
Dog.prototype.introduce = function() {
return "안녕! 나는 " + this.age + "살 " + this.breed + " " + this.name + "이야!";
};
// 프로토타입에 놀기 기능 추가
Dog.prototype.play = function(toy) {
this.energy -= 10;
this.happiness += 20;
if (this.happiness > 100) this.happiness = 100;
return this.name + "이(가) " + toy + "와 신나게 놀아요! 행복도: " + this.happiness;
};
// 프로토타입에 잠자기 기능 추가
Dog.prototype.sleep = function() {
this.energy = 100;
return this.name + "이(가) 잘 자서 에너지가 가득해요!";
};
// 강아지들 만들기
let dog1 = new Dog("뽀삐", "치와와", 2);
let dog2 = new Dog("초코", "골든리트리버", 3);
console.log(dog1.introduce()); // "안녕! 나는 2살 치와와 뽀삐이야!"
console.log(dog1.bark()); // "뽀삐이(가) 멍멍! 짖어요 (에너지: 95)"
console.log(dog1.play("공")); // "뽀삐이(가) 공와 신나게 놀아요! 행복도: 70"
console.log(dog2.sleep()); // "초코이(가) 잘 자서 에너지가 가득해요!"
// 중요한 확인: 두 강아지가 같은 기능을 공유하고 있어요
console.log(dog1.bark === dog2.bark); // true (같은 기능을 공유)
🔹 스마트폰 만들기
// 스마트폰 생성자 함수
function SmartPhone(brand, model, color) {
this.brand = brand;
this.model = model;
this.color = color;
this.battery = 100;
this.isOn = false;
this.apps = [];
}
// 전원 켜기/끄기 기능
SmartPhone.prototype.togglePower = function() {
this.isOn = !this.isOn;
let status = this.isOn ? "켜졌어요" : "꺼졌어요";
return this.brand + " " + this.model + "이(가) " + status;
};
// 앱 설치하기 기능
SmartPhone.prototype.installApp = function(appName) {
if (!this.isOn) {
return "먼저 전원을 켜주세요!";
}
this.apps.push(appName);
this.battery -= 5;
return appName + " 앱이 설치되었어요! 배터리: " + this.battery + "%";
};
// 배터리 충전하기 기능
SmartPhone.prototype.charge = function(amount) {
this.battery += amount;
if (this.battery > 100) this.battery = 100;
return "충전 완료! 현재 배터리: " + this.battery + "%";
};
// 폰 정보 보기 기능
SmartPhone.prototype.getInfo = function() {
let powerStatus = this.isOn ? "켜짐" : "꺼짐";
return `${this.color} ${this.brand} ${this.model} - 전원: ${powerStatus}, 배터리: ${this.battery}%, 앱 개수: ${this.apps.length}개`;
};
// 스마트폰들 만들기
let iPhone = new SmartPhone("애플", "아이폰15", "블루");
let galaxy = new SmartPhone("삼성", "갤럭시S24", "화이트");
console.log(iPhone.togglePower()); // "애플 아이폰15이(가) 켜졌어요"
console.log(iPhone.installApp("게임앱")); // "게임앱 앱이 설치되었어요! 배터리: 95%"
console.log(iPhone.getInfo()); // "블루 애플 아이폰15 - 전원: 켜짐, 배터리: 95%, 앱 개수: 1개"
console.log(galaxy.charge(10)); // "충전 완료! 현재 배터리: 100%"
🔹 게임 플레이어 만들기
// 게임 플레이어 생성자 함수
function GamePlayer(name, character) {
this.name = name;
this.character = character;
this.level = 1;
this.exp = 0;
this.hp = 100;
this.gold = 0;
this.inventory = [];
}
// 몬스터 잡기 기능
GamePlayer.prototype.fightMonster = function(monsterName) {
let expGain = Math.floor(Math.random() * 50) + 10; // 10~59 경험치
let goldGain = Math.floor(Math.random() * 20) + 5; // 5~24 골드
this.exp += expGain;
this.gold += goldGain;
let message = `${this.name}이(가) ${monsterName}을 잡았어요! 경험치 +${expGain}, 골드 +${goldGain}`;
// 레벨업 체크
if (this.exp >= this.level * 100) {
this.exp -= this.level * 100;
this.level += 1;
this.hp += 20;
message += ` 🎉 레벨업! ${this.level}레벨이 되었어요!`;
}
return message;
};
// 아이템 사기 기능
GamePlayer.prototype.buyItem = function(itemName, price) {
if (this.gold >= price) {
this.gold -= price;
this.inventory.push(itemName);
return `${itemName}을(를) 구매했어요! 남은 골드: ${this.gold}`;
} else {
return "골드가 부족해요!";
}
};
// 플레이어 상태 보기 기능
GamePlayer.prototype.getStatus = function() {
return `${this.name} (${this.character}) - 레벨: ${this.level}, HP: ${this.hp}, 골드: ${this.gold}, 인벤토리: ${this.inventory.length}개`;
};
// 체력 회복하기 기능
GamePlayer.prototype.heal = function() {
this.hp = 100;
return this.name + "의 체력이 완전히 회복되었어요!";
};
// 게임 플레이어들 만들기
let player1 = new GamePlayer("용사민수", "전사");
let player2 = new GamePlayer("마법사지영", "마법사");
console.log(player1.fightMonster("고블린")); // "용사민수이(가) 고블린을 잡았어요! 경험치 +35, 골드 +12"
console.log(player1.buyItem("철검", 100)); // "골드가 부족해요!"
console.log(player1.fightMonster("오크")); // "용사민수이(가) 오크을 잡았어요! 경험치 +42, 골드 +18"
console.log(player1.getStatus()); // "용사민수 (전사) - 레벨: 1, HP: 100, 골드: 30, 인벤토리: 0개"
🔄 프로토타입 vs 개별 메서드 비교하기
실제로 메모리 사용량이 어떻게 다른지 살펴보는 시간이에요. 마치 도시락을 각자 싸오는 것과 급식을 먹는 것의 차이를 생각해보면 이해하기 쉬울 거예요.
개별 메서드 방식 (메모리를 많이 사용):
function Robot(name) {
this.name = name;
// 각 로봇마다 개별적으로 기능을 만들어요 - 메모리 낭비!
this.work = function() {
return this.name + "이(가) 열심히 일해요";
};
this.rest = function() {
return this.name + "이(가) 휴식을 취해요";
};
}
let robot1 = new Robot("로보1");
let robot2 = new Robot("로보2");
let robot3 = new Robot("로보3");
// 각 로봇이 다른 기능들을 가지고 있어요 (메모리 3배 사용)
console.log(robot1.work === robot2.work); // false (다른 기능들)
console.log(robot2.work === robot3.work); // false (다른 기능들)
프로토타입 메서드 방식 (메모리를 아껴 사용):
function Robot(name) {
this.name = name;
}
// 모든 로봇이 공유하는 기능 - 메모리 절약!
Robot.prototype.work = function() {
return this.name + "이(가) 열심히 일해요";
};
Robot.prototype.rest = function() {
return this.name + "이(가) 휴식을 취해요";
};
let robot1 = new Robot("로보1");
let robot2 = new Robot("로보2");
let robot3 = new Robot("로보3");
// 모든 로봇이 같은 기능을 공유해요 (메모리 1배만 사용)
console.log(robot1.work === robot2.work); // true (같은 기능을 공유)
console.log(robot2.work === robot3.work); // true (같은 기능을 공유)
// 하지만 결과는 똑같아요!
console.log(robot1.work()); // "로보1이(가) 열심히 일해요"
console.log(robot2.work()); // "로보2이(가) 열심히 일해요"
결론: 프로토타입 방식은 같은 결과를 내면서도 메모리를 훨씬 적게 사용해요!
🚨 자주 하는 실수들
❌ 실수 1: 일반 객체에 prototype 사용하기
let myObject = { name: "테스트" };
// 잘못된 방법 - 일반 객체에는 prototype이 없어요
// myObject.prototype.sayHello = function() { ... }; // 에러!
console.log(myObject.prototype); // undefined
❌ 실수 2: 생성자 함수 자체에 메서드 추가하기
function Person(name) {
this.name = name;
}
// 잘못된 방법 - 생성자 함수 자체에 추가
Person.sayHello = function() {
return "안녕하세요!";
};
let person = new Person("철수");
// person.sayHello(); // 에러! 사용할 수 없어요
// 생성자 함수는 직접 사용할 수 있지만, 인스턴스는 사용할 수 없어요
console.log(Person.sayHello()); // "안녕하세요!" - 이건 가능
// console.log(person.sayHello()); // 에러!
// 올바른 방법 - prototype에 추가
Person.prototype.sayHello = function() {
return "안녕하세요, " + this.name + "이에요!";
};
console.log(person.sayHello()); // "안녕하세요, 철수이에요!" - 이제 가능!
❌ 실수 3: 화살표 함수로 프로토타입 메서드 만들기
function Cat(name) {
this.name = name;
}
// 잘못된 방법 - 화살표 함수는 this가 다르게 작동해요
Cat.prototype.meow = () => {
return this.name + "이(가) 야옹"; // this가 제대로 작동하지 않아요
};
// 올바른 방법 - 일반 함수 사용
Cat.prototype.meow = function() {
return this.name + "이(가) 야옹";
};
✏️ 연습 문제를 시작하기 전에
이제 여러분이 직접 프로토타입 메서드를 만들어볼 시간이에요. 마치 처음 자전거를 배울 때처럼 조금씩 천천히 해보면 돼요. 넘어져도 괜찮고, 틀려도 괜찮아요. 그렇게 하나씩 익혀가다 보면 어느새 자연스럽게 프로토타입을 다룰 수 있을 거예요.
오늘 배운 것들이 어렵게 느껴져도 걱정하지 마세요. 물이 땅속으로 스며들듯이, 배움도 천천히 스며들어요. 급하게 하려고 하지 말고, 하나씩 차근차근 따라해보세요.
🔸 기초 연습 1: 간단한 계산기 만들기
function Calculator(name) {
this.name = name;
this.result = 0;
}
// 더하기 기능을 프로토타입에 추가해보세요
Calculator.prototype.add = function(num) {
this.result += num;
return this.result;
};
// 빼기 기능을 프로토타입에 추가해보세요
Calculator.prototype.subtract = function(num) {
this.result -= num;
return this.result;
};
// 결과 초기화 기능을 프로토타입에 추가해보세요
Calculator.prototype.reset = function() {
this.result = 0;
return this.name + " 계산기 초기화 완료!";
};
// 테스트
let calc = new Calculator("내 계산기");
console.log(calc.add(10)); // 10
console.log(calc.subtract(3)); // 7
console.log(calc.reset()); // "내 계산기 계산기 초기화 완료!"
🔸 기초 연습 2: 책 만들기
function Book(title, author, pages) {
this.title = title;
this.author = author;
this.pages = pages;
this.currentPage = 0;
}
// 책 소개 기능을 프로토타입에 추가해보세요
Book.prototype.introduce = function() {
return `"${this.title}"은 ${this.author}이 쓴 ${this.pages}페이지 책이에요`;
};
// 책 읽기 기능을 프로토타입에 추가해보세요
Book.prototype.read = function(pages) {
this.currentPage += pages;
if (this.currentPage > this.pages) {
this.currentPage = this.pages;
}
let progress = Math.round((this.currentPage / this.pages) * 100);
return `현재 ${this.currentPage}/${this.pages}페이지 (${progress}%) 읽었어요`;
};
let book = new Book("해리포터", "J.K. 롤링", 400);
console.log(book.introduce()); // "'해리포터'은 J.K. 롤링이 쓴 400페이지 책이에요"
console.log(book.read(100)); // "현재 100/400페이지 (25%) 읽었어요"
🔸 중급 연습: 은행 계좌 만들기
function BankAccount(owner, initialBalance) {
this.owner = owner;
this.balance = initialBalance;
this.transactionHistory = [];
}
// 입금 기능을 추가해보세요
BankAccount.prototype.deposit = function(amount) {
this.balance += amount;
this.transactionHistory.push(`입금: +${amount}원`);
return `${amount}원 입금완료. 잔액: ${this.balance}원`;
};
// 출금 기능을 추가해보세요
BankAccount.prototype.withdraw = function(amount) {
if (this.balance >= amount) {
this.balance -= amount;
this.transactionHistory.push(`출금: -${amount}원`);
return `${amount}원 출금완료. 잔액: ${this.balance}원`;
} else {
return "잔액이 부족합니다!";
}
};
// 계좌 정보 보기 기능을 추가해보세요
BankAccount.prototype.getAccountInfo = function() {
return `${this.owner}님의 계좌 - 잔액: ${this.balance}원, 거래내역: ${this.transactionHistory.length}건`;
};
let myAccount = new BankAccount("김학생", 10000);
console.log(myAccount.deposit(5000)); // "5000원 입금완료. 잔액: 15000원"
console.log(myAccount.withdraw(3000)); // "3000원 출금완료. 잔액: 12000원"
console.log(myAccount.getAccountInfo()); // "김학생님의 계좌 - 잔액: 12000원, 거래내역: 2건"
📚 복습하기 - 15단원 클래스와 비교해보기
지난 시간에 배운 클래스와 오늘 배운 프로토타입 메서드는 비슷한 결과를 만들어요. 차이점을 알아보며 복습해보겠어요!
복습 문제 1: 같은 기능을 다른 방법으로 만들기
클래스 방식 (15단원에서 배운 방법):
class Animal {
constructor(name, species) {
this.name = name;
this.species = species;
this.energy = 100;
}
makeSound() {
this.energy -= 5;
return this.name + "이(가) " + this.species + " 소리를 내요 (에너지: " + this.energy + ")";
}
sleep() {
this.energy = 100;
return this.name + "이(가) 잠을 자서 기력이 회복되었어요";
}
}
let cat = new Animal("야옹이", "고양이");
console.log(cat.makeSound()); // "야옹이이(가) 고양이 소리를 내요 (에너지: 95)"
프로토타입 방식 (오늘 배운 방법):
function Animal(name, species) {
this.name = name;
this.species = species;
this.energy = 100;
}
Animal.prototype.makeSound = function() {
this.energy -= 5;
return this.name + "이(가) " + this.species + " 소리를 내요 (에너지: " + this.energy + ")";
};
Animal.prototype.sleep = function() {
this.energy = 100;
return this.name + "이(가) 잠을 자서 기력이 회복되었어요";
};
let dog = new Animal("멍멍이", "강아지");
console.log(dog.makeSound()); // "멍멍이이(가) 강아지 소리를 내요 (에너지: 95)"
차이점 정리:
특징 | 클래스 방식 | 프로토타입 방식 |
---|---|---|
키워드 | class |
function |
속성 정의 | constructor 안에 |
생성자 함수 안에 |
메서드 정의 | 클래스 본문에 바로 | prototype 에 별도로 추가 |
코드 구조 | 모든 것이 한 곳에 모임 | 메서드가 따로 정의됨 |
사용법 | 둘 다 new 키워드로 객체 생성 |
동일 |
복습 문제 2: 클래스를 프로토타입으로 바꿔보기
다음 클래스를 프로토타입 방식으로 바꿔보세요:
// 클래스 버전 (15단원에서 배운 방법)
class Rectangle {
constructor(width, height) {
this.width = width;
this.height = height;
this.color = "하얀색";
}
getArea() {
return this.width * this.height;
}
getPerimeter() {
return (this.width + this.height) * 2;
}
paint(color) {
this.color = color;
return "사각형을 " + color + "으로 칠했어요";
}
describe() {
return `${this.color} 사각형 (${this.width}×${this.height}) - 넓이: ${this.getArea()}`;
}
}
// 프로토타입 버전으로 바꿔보세요!
function Rectangle(width, height) {
this.width = width;
this.height = height;
this.color = "하얀색";
}
Rectangle.prototype.getArea = function() {
return this.width * this.height;
};
Rectangle.prototype.getPerimeter = function() {
return (this.width + this.height) * 2;
};
Rectangle.prototype.paint = function(color) {
this.color = color;
return "사각형을 " + color + "으로 칠했어요";
};
Rectangle.prototype.describe = function() {
return `${this.color} 사각형 (${this.width}×${this.height}) - 넓이: ${this.getArea()}`;
};
// 테스트 (두 방법 모두 같은 결과가 나와요)
let rect = new Rectangle(5, 3);
console.log(rect.getArea()); // 15
console.log(rect.paint("빨강")); // "사각형을 빨강으로 칠했어요"
console.log(rect.describe()); // "빨강 사각형 (5×3) - 넓이: 15"
복습 문제 3: 어떤 방법이 더 좋을까요?
질문: 클래스와 프로토타입 중 어떤 방법이 더 좋을까요?
답:
- 클래스는 더 깔끔하고 읽기 쉬워요. 모든 코드가 한 곳에 모여있어서 관리하기 편해요.
- 프로토타입은 더 기본적인 방법이고, 자바스크립트의 동작 원리를 더 잘 이해할 수 있어요.
- 메모리 사용량은 둘 다 비슷해요. (둘 다 프로토타입을 내부적으로 사용해요)
- 성능도 거의 차이가 없어요.
- 최근에는 클래스를 더 많이 사용하는 추세지만, 프로토타입을 이해하면 자바스크립트를 더 깊이 알 수 있어요!
🎁 보너스: 신기한 프로토타입 특징들
더 깊이 알고 싶은 분들을 위한 내용이에요. 어려우면 나중에 봐도 괜찮아요!
특징 1: 나중에 프로토타입 메서드 변경하기
function Toy(name) {
this.name = name;
}
Toy.prototype.play = function() {
return this.name + "와 놀아요!";
};
let toy1 = new Toy("곰돌이");
console.log(toy1.play()); // "곰돌이와 놀아요!"
// 나중에 메서드를 바꿔요
Toy.prototype.play = function() {
return this.name + "와 더 재미있게 놀아요!";
};
console.log(toy1.play()); // "곰돌이와 더 재미있게 놀아요!"
신기하죠? 이미 만들어진 객체도 바뀐 기능을 사용해요!
특징 2: 나중에 새로운 메서드 추가하기
function Car(brand) {
this.brand = brand;
}
let myCar = new Car("현대");
// 나중에 새로운 기능을 추가해요
Car.prototype.honk = function() {
return this.brand + " 자동차가 빵빵!";
};
// 이미 만들어진 자동차도 새 기능을 사용할 수 있어요!
console.log(myCar.honk()); // "현대 자동차가 빵빵!"
📝 정리하기
오늘은 프로토타입 메서드에 대해 배웠어요:
- 프로토타입 메서드는 모든 객체가 공유하는 공통 기능이에요
- 메모리를 아껴쓰고 관리하기 쉬워요
생성자함수.prototype.메서드이름 = function() { ... }
형태로 만들어요- 클래스 메서드와 비슷한 역할을 하지만 문법이 다르고, 더 유연해요
- 나중에 기능을 추가하거나 변경할 수 있어요
프로토타입 메서드를 잘 사용하면 더 효율적이고 유연한 코드를 만들 수 있어요!
✅ 학습 완료 체크리스트
학습 내용 | 이해했나요? |
---|---|
프로토타입 메서드의 기본 개념 | ✅ |
프로토타입에 메서드 추가하는 방법 | ✅ |
개별 메서드와의 차이점 | ✅ |
메모리 절약 효과 | ✅ |
클래스 메서드와의 비교 | ✅ |
자주 하는 실수들 | ✅ |
프로토타입의 유연성 | ✅ |
📂 마무리 정보
오늘 배운 16.2.2
내용이 여러분의 자바스크립트 지식 상자에 잘 저장되었나요? 다음 시간에는 더 재미있는 내용으로 만나요!
기억할 점: 프로토타입 메서드는 모든 객체가 함께 사용하는 공통 기능이에요. 마치 우리 동네 도서관의 참고서처럼 모두가 공유해서 사용할 수 있답니다!
무료 JavaScript 학습 플랫폼에서 단계별 학습과 실시간 코드 실행을 통해
더욱 효과적이고 재미있게 학습하실 수 있습니다.
'16. 프로토타입과 상속의 비밀 > 16.2 생성자 함수 상속' 카테고리의 다른 글
16.2.3 상속 구현하기 - 부모님의 능력을 물려받기 (0) | 2025.07.24 |
---|---|
16.2.1 생성자 함수로 객체 만들기 - 나만의 공장 세우기 (0) | 2025.07.24 |