프로토타입과 클래스

JiHun·2023년 5월 11일
0

JavaScript

목록 보기
4/5

💼 프로토타입(prototype)

프로토타입은 원형을 뜻한다. 왜 프로토타입이 쓰일까?
결론만 말하자면, 객체 간 상속을 구현하기 위해 사용된다.
프로토타입은 어떤 객체의 상위(부모) 객체의 역할을 하는 객체로서 다른 객체에 공유 프로퍼티를 제공한다.

🗂️ 왜 프로토타입 쓸까?

📑문제

메서드를 그냥 프로퍼티를 선언할 경우 어떤 문제가 생길까?

// ES5 문법
function 사람(age) {
	this.age = age;
    this.speak = function() {
    	return `저는 ${this.age}살 입니다.`
    }
}

const 사람1 = new 사람(11);
const 사람2 = new 사람(22);


console.log(사람1.speak === 사람2.speak); // false
console.log(사람1.speak);  // "저는 11살 입니다."
console.log(사람2.speak);  // "저는 22살 입니다."

사람1, 사람2에게 상속을 했다. 여기서 speak() 메서드를 서로 둘 다 쓸 수 있다.
함수는 똑같이 생겼지만 서로 다르다고 출력한다. 서로 다른 인스턴스에 상속돼서 다른 함수로 취급받는 것이다. 내용이 동일한 메서드가 중복으로 생성됐다. 이것은 메모리 측면에서 비효율적이다.
모든 인스턴스들이 동일한 내용의 메서드를 사용하므로 단 하나만 생성하여 모든 인스턴스가 공유하는 것이 효율적일 것이다.
하지만 생성자 함수 사람는 인스턴스를 생성할 때마다 speak 메서드를 중복 생성하고 모든 인스턴스가 중복 소유한다.

자바스크립트는 프로토타입을 기반으로 상속을 구현하여 불필요한 중복을 제거한다.

📑해결방법

function 사람(age) {
	this.age = age;
}

// 모든 인스턴스들이 공유 사용하게 프로토타입에 추가한다.
// 프로토타입은 사람 생성자 함수의 prototype이라는 프로퍼티에 바인딩 되어있다.
사람.prototype.speak = function() {
	return `저는 ${this.age}살 입니다.`
}

const 사람1 = new 사람(11);
const 사람2 = new 사람(22);

console.log(사람1.speak === 사람2.speak); // true;
console.log(사람1.speak);  // "저는 11살 입니다."
console.log(사람2.speak);  // "저는 22살 입니다."

모든 인스턴스는 부모 객체의 역할을 하는 프로토타입으로부터 메서드를 상속받는다.
상속 받은 프로토타입에 있는 하나의 메서드를 공유한다.

🗂️ 클래스, 인스턴스, 프로토타입의 관계

프로토타입은 클래스의 부모역할을 대신한다.
객체가 생설될 때, 객체 생성 방식에 따라 프로토타입이 결정되고, 객체와 바인딩 되는 내부 슬롯 [[Prototype]]에 저장된다.

각 클래스, 인스턴스, 프로토타입 객체들은 서로에게 접근할 수 있는 프로퍼티를 갖고 있다.
천천히 알아보자.

📑 .__proto__(인스턴스 -> 프로토타입)

먼저 클래스로 생성된(상속받은) 인스턴스에서부터 시작해보자.
인스턴스에서 프로토타입을 불러오고 싶다면 사람1._proto__
프로토타입을 불러온다.

📑 .constructor(프로토타입 -> 클래스)

이제는 프로토타입 관점에서
사람.prototype.constructor을 쓰게 되면 클래스를 불러온다.

📑 .prototype(클래스 -> 프로토타입)

이제는 클래스의 관점에서 프로토타입을 불러오고 싶다면 사람.prototype

📝 이제 보니까 객체에서 프로토타입을 부르는 것과 클래스에서 프로토타입을 부르는 것이 같고,
prototype가 상속받은 메서드와 객체가 상속받은 메서드가 같다!!!

profile
안녕하세요. 프론트엔드 개발자 송지훈입니다.

0개의 댓글