자바스크립트의 프로토타입(Prototype) 이해하기

juny_0429·2023년 4월 22일
0

자바스크립트는 프로토타입 기반 언어이기 때문에 클래스라는 개념 대신 프로토타입(Prototype)이 존재합니다.
클래스가 없으니 기본적으로 상속기능이 없기에 프로토타입으로 상속을 흉내내서 구현합니다.

이에 따라, 이번 글에서는 자바스크립트에서 프로토타입이 무엇인지에 대해 설명하고, 프로토타입 공부 시 헷갈릴 수 있는 부분에 대해 설명하고자 합니다.

참고로 2015년 6월에 발표된 ECMA6(또는 ES6) 표준에서는 Class 문법이 추가되었습니다.

ES6에서는 클래스 문법을 도입하여 객체 지향 프로그래밍에서 사용되는 클래스를 더욱 쉽고 간결하게 표현할 수 있게 되었습니다.
하지만 이는 문법이 추가되었다는 것일 뿐, 자바스크립트가 클래스 기반 언어로 변경된 것은 아니므로, 이에 대해 공부하면서 차근차근 이해해 나가는 것이 중요합니다.



들어가기에 앞서

- JavaScript에서 모든 객체는 프로토타입(Prototype)을 가지며, 이 프로토타입은 해당 객체가 상속받는 속성과 메서드를 포함합니다.

- 객체의 프로토타입은 내부적으로 proto 라는 속성에 저장되어 있습니다.

이 두 문장을 생각하며 본문으로 들어가봅시다.



프로토타입(Prototype)이란?


가장 중요한 개념은

함수를 생성하면 해당 함수의 프로토타입 객체(Prototype Object)도 함께 생성됩니다.
이 프로토타입 객체는 해당 함수로부터 생성된 모든 객체의 부모 역할을 합니다.

입니다. 위 개념만 이해하고 넘어간다면 프로토타입에 대한 기본적인 개념은 이해할수 있습니다.

  • [[Prototype]]
    • 함수를 포함한 모든 객체가 가지고 있는 인터널 슬롯
    • 객체의 입장에서 자신의 부모 역할을 하는 프로토타입 객체를 가리키며 함수 객체의 경우 Function.prototype를 가리킨다

  • prototype 속성
    • 함수 객체만 가지고 있는 속성
    • 함수 객체가 생성자로 사용될 때 이 함수를 통해 생성될 객체의 부모 역할을 하는 객체(프로토타입 객체)를 가리킨다.
    • 함수 객체만이 소유하는 prototype 프로퍼티는 생성자 함수가 생성할 인스턴스의 프로토타입을 가리킨다.

  • constructor 속성
    • 프로토타입 객체는 constructor 속성을 갖는다.
    • constructor 속성은 객체 입장에서 자신을 생성한 객체를 가리킨다.
      -> 여기서 자신을 생성한 객체는 함수를 선언할 때 같이 생성된 프로토타입 객체를 가리킨다.
    • constructor 속성을 통해 해당 객체를 생성한 함수가 무엇인지 알 수 있다.


위 그림을 보며 쉽게 생각해봅시다.

함수 = 틀
함수 내 prototype 속성 = "틀 만들면서 찍어낸 원본이 뭐야?"
.prototype = 틀을 만들면서 함께 만들어진 원본
constructor 속성 = "널 만들 때 사용한 틀은 뭐야?"
__proto__ 속성 = "너의 원본은 뭐야?"


위 그림을 보면 Person 함수를 생성하면 함수의 객체도 함께 생성된다고 했죠?

Person 함수의 객체는 Person.prototype 입니다.
그러면 constructor는 "널 만들 때 사용한 틀은 뭐야?" 였죠?

Person.prototype.constructor === Person

는 true가 나오게 됩니다.



코드를 보며 설명해보겠습니다.
함수를 하나 생성하고 객체를 만들어줍니다.

function Person(name) {
	this.name = name;
}

let foo = new Person('Park');

여기서

Person.prototype.constructor === Person

Person 함수에 의해 생성된 객체의 생성자는? 이라고 했을 때 Person 함수가 나오게 됩니다.


foo.constructor === Person

new로 객체생성을 했을 때 생성한 객체의 생성자는? 이라고 했을 때도 Person 함수가 나옵니다.



constructor 말고 __proto__도 알아보겠습니다.

__proto__ 는 자신의 부모 역할을 하는 객체를 가리키게 되는데
"너의 원본이 어떤거야?"라고 생각하면 이해하기 쉽습니다.

foo.__proto__ === Person.prototype

Person로 new 해서 생성한 객체의 원본이 뭐야? 라고 했을 때
해당 함수를 생성하면서 함께 생성된 객체를 가리키게 됩니다.



위 그림중 설명하지 않은 두개가 있습니다.

  • Object.prototype
  • Function.prototype

Object.prototype

자바스크립트에서 모든 객체의 부모 객체 이며,
기본적으로 모든 객체가 상속하는 프로토타입입니다.

Object.prototype 객체에는 자바스크립트에서 사용되는 기본적인 메서드들이 정의되어 있습니다.

예를 들어, toString(), hasOwnProperty(), valueOf()와 같은 메서드들이 Object.prototype 객체에 정의되어 있습니다.

이러한 메서드들은 자바스크립트에서 모든 객체에서 사용할 수 있으며, 필요한 경우에는 상속받아 사용할 수도 있습니다.


Function.prototype

모든 함수 객체의 부모 객체 이며,
기본적으로 모든 함수 객체가 상속하는 프로토타입입니다.

Function.prototype 객체에는 함수 객체에서 사용할 수 있는 기본적인 메서드들이 정의되어 있습니다.

예를 들어, apply(), call(), bind()와 같은 메서드들이 Function.prototype 객체에 정의되어 있습니다.

이러한 메서드들은 자바스크립트에서 함수 객체에서 자주 사용되며,
필요한 경우에는 상속받아 사용할 수도 있습니다.


쉽게 얘기해서 Fuction.prototype 은 모든 함수 객체가 상속하는 프로토타입 객체이고,
Object.prototype 은 모든 객체가 상속하는 프로토타입이다.

여기서 자바스크립트의 함수는 객체의 일종이기 때문에 함수 최상위에 위치하는 객체는 
Fuction.prototype 이고 Fuction.prototype 의 상위 
즉, Fuction.prototype.__proto__ 는 모든 객체의 최상위인 
Object.prototype 이 되는 겁니다.

이렇게 최대한 쉽게 prototype에 대해 알아보았습니다.
좀더 깊게 알고 싶다면 책이나 다른분들의 블로그를 참고하시면 도움이 많이 될것 같습니다.

무엇보다 중요한건 실제로 함수를 생성해보고 콘솔창에 비교를 해보며, true/false 값을 스스로 확인하는 것이 가장 좋습니다.

0개의 댓글