오늘은 자바스크립트에서의 프로토타입에 대해 알아보겠습니다!
프로토타입이란? 🤷🏻♀️
프로토타입은 어떤 객체의 상위 객체의 역할을 하는 객체로서 다른 다른 객체에 공유 프로퍼티를 제공한다.
따라서 프로토타입을 상속받은 하위 객체는 상위 객체의 프로퍼티를 자신의 프로퍼티처럼 자유롭게 사용이 가능하다.
말이 좀 어렵죠?! 쉽게 말해 프로토타입을 기반으로 상속을 구현한다는 이야기입니다!
보통 객체지향 언어에서는 클래스를 통해 상속을 구현합니다. 자바스크립트는 ES6의 클래스가 추가되기 전에 상속의 형태를 프로토타입으로 구현하였습니다.
프로토타입이 왜 쓰이는가? ⁉️
그렇다면 프로토타입을 왜 쓸까요? 당연히 상속을 구현하기 위해..
자바스크립트에서는 객체를 생성할 때, 생성자 함수를 통해 생성하는 등의 방법을 사용합니다.
이러한 방법은 동일한 프로퍼티 구조를 가지는 객체를 여러 개 생성할 때 유용하게 사용할 수 있습니다.
// 1. 생성자 함수
function Circle(radius) {
this.radius = radius;
this.getArea = function() {
return Math.PI * this.radius ** 2;
};
}
// 2. 객체 생성
const circle1 = new Circle(1);
const circle2 = new Circle(2);
// 3. 결과
console.log(circle1.getArea === circle2.getArea); //false
위 코드에서는 생성자 함수를 통해 2개의 객체를 생성하였습니다.
원의 반지름 프로퍼티, 원의 넓이를 구하는 메서드를 하나 포함하고 있지요.
하지만 이런 식 (생성자 함수를 통해)으로 객체를 생성했을 시에 문제점이 있습니다. ⚠️

생성자 함수 내의 메서드를 각각 갖는다는 것입니다. 즉, 동일한 메서드가 2개 생기게 되는 것입니다.
이것은 불필요한 메모리를 낭비하게 됩니다 ‼️
이러한 문제를 해결하기 위해서는 어떻게 해야할까요?
하나만 생성하여 공유하자!!
맞습니다 !!
중복되는 메서드를 하나만 생성하여 불필요한 중복을 제거하기 위해 프로토타입을 사용합니다.
프로토타입의 사용 🧑🏻🔧
이번엔 프로토타입을 어떻게 사용하는지에 대해 알아보도록 하겠습니다.
// 1. 생성자 함수
function Circle(radius) {
this.radius = radius;
}
// 2. 프로토타입에 추가
Circle.prototype.getArea = function() {
return Math.PI * this.radius ** 2;
};
// 3. 객체 생성
const circle1 = new Circle(1);
const circle2 = new Circle(2);
// 4. 결과
console.log(circle1.getArea === circle2.getArea); // true
2번에서 볼 수 있듯이 프로토타입은 Circle 생성자 함수의 prototype 프로퍼티에 바인딩 되어 있습니다.
또한, 프로토타입을 통해 메서드를 추가하게 되면 4번에서 볼 수 있듯이 동일한 메서드를 공유하게 됩니다.

생성자 함수가 프로토타입 객체와 연결되어있고 Circle 생성자 함수로 생성한 객체들은 프로토타입 객체를 참조하고 있습니다.
그렇다면 circle1, circle2 객체들은 프로토타입 객체를 어떻게 참조하는 것일까요??
프로토타입 객체 😊
프로토타입 객체를 보기전에 함수가 정의되는 과정에서 일어나는 일에 대해 한번 확인해보겠습니다.
첫번째는 함수에 생성자 자격을 부여합니다. 두번째로는 해당 함수에 Prototype 객체를 생성하고 연결합니다.
이렇게 생성된 함수는 prototype이라는 프로퍼티를 가지게 되고, 생성된 프로토타입 객체에 해당 프로퍼티로 접근할 수 있게 됩니다.
이와 같은 과정을 거쳐
위 사진의 구조를 갖게 되는것입니다.
자 이제 프로토타입 객체에 대해 보겠습니다.
프로토타입 객체는 일반 객체와 크게 다르지 않습니다. 일반적인 객체들과 같이 constructor와 _ _ _ proto _ _ _ 를 가집니다.
잠깐!! _ _ _ proto _ _ _ 이게 뭐져..??
_ _ _ proto _ _ _ 는 접근자 프로퍼티 입니다 !!
접근자 프로퍼티 ‼️
모든 객체는 _ _ _ proto _ _ _ 접근자 프로퍼티를 통해 자신의 프로토타입에 간접적으로 접근할 수 있다.
접근자 프로퍼티는 자체적으로는 값을 갖지 않고 다른 데이터 프로퍼티의 값을 읽거나 저장할 때 사용하는 접근자 함수로 구성된 프로퍼티입니다.

그림처럼 생성자 함수를 통해 만들어진 객체는 _ _ _ proto _ _ _ 를 통해 접근하여 프로토타입을 얻습니다.
정리 🧹
공부하며 적은 글이라 빠진 내용도 많고,, 그렇지만,,,,!
정리를 해보자면

프로토타입은 prototype 프로퍼티와 접근자 프로퍼티인 _ _ _ proto_ _ _ 를 가집니다.
접근자 프로퍼티인 _ _ _ proto_ _ _ 는 모든 객체가 소유하고 있고, 모든 객체가 사용합니다. 또한, 객체가 자신의 프로토타입에 접근하고 교체하기 위해 사용됩니다.
prototype 프로퍼티는 함수 객체만이 소유하고 있고, 생성자 함수가 사용합니다.
또한, 생성자 함수가 자신이 생성할 객체의 프로토타입을 할당하기 위해 사용됩니다.
하지만 중요한 것은 둘다 같은 프로토타입을 가리킨다 는 것입니다!!
긴글 읽어주셔서 감사합니다😊
참고 📜
https://medium.com/@bluesh55/javascript-prototype-이해하기-f8e67c286b67
▶황재호. 『예제로 배우는 자바스크립트』. 인포앤북, 2023.
▶이웅모. 『모던 자바스크립트 Deep dive』. 위키북스, 2020.