JavaScript는 prototype 기반의 언어이다.
JavaScript로 개발을 한다면 빠질 수 없는 것이 prototype이라고는 하는데 사실 오늘 보면서 무슨 말인지 정말 모르겠다
하지만 어떤 틀이 생기고 그 틀을 기준으로 무엇인가 돌아간다는 두루뭉술한 느낌은 알겠다.
먼저 JavaScript에서의prototype을 알아보기 전에 prototype 자체의 단어 의미를 알아보고 왜 prototype이라고 하는지 알아보려고 한다.
⇒ 나무위키 사전 정의에서 prototype은 원래의 형태 또는 전형적인 예, 기초 또는 표준이다.
'정보시스템의 미완성 버전 또는 중요한 기능들이 포함되어 있는 시스템의 초기모델'이다.
prototype은 원형 객체를 의미한다.
JavaScript에서 기본 데이터 타입을 제외한 모든 것이 객체인데, 객체가 만들어지기 위해서는 자신을 만드는 데 사용된 원형인 프로토타입 객체를 이용하여 객체를 만든다.
이 때 만들어진 객체 안에 proto(비표준)속성이 자신을 만들어낸 원형을 의미하는 프로토타입 객체를 참조하는 숨겨진 링크가 있다. 이 숨겨진 링크를 프로토타입이라고 정의한다.
객체를 만들고 그 안에 있는 값을 가져다 쓸 수 있게 만드는 것이 바로 prototype이다!
<예시코드>
function Person() {...}
Person.prototype.eyes = 2;
Person.prototype.nose = 1;
let kim = new Person();
let park = new Person():
console.log(kim.eyes); // => 2
Person.prototype이라는 빈 Object가 어딘가에 존재하고, Person 함수로부터 생성된 객체(kim, park)들은 어딘가에 존재하는 Object에 들어있는 값을 모두 갖다쓸 수 있다.
즉, eyes와 nose를 어딘가에 있는 빈 공간에 넣어놓고 kim과 park이 공유해서 사용하는 것이다.
프로토타입은 왜 쓰는 것일까?
프로토타입과 인스턴스 객체는 proto 프로퍼티를 가지고 있기 때문에 해당 프로퍼티를 통해 상위 프로토타입에 접근할 수 있다. 그리고 상위 프로토타입의 프로퍼티 및 메서드에 접근할 수 있다. 이러한 특징을 통해 중복된 코드 줄일 수 있고, 재사용성을 높일 수 있다.
.__proto__
접근하고자 하는 객체의 내부 속성인 prototype를 노출하는 접근자 속성 함수이다.
모든 객체는 __proto__
를 통해 자신의 프로토타입([[Prototype]]
내부 슬롯)에 접근할 수 있다.
<예시코드>
const 꼬부기 = {};
const 이브이 = {};
꼬부기.__proto__ = 이브이;
이브이.__proto__ = 꼬부기;
하지만 [[Prototype]]
내부 슬롯에는 직접 접근이 불가하다. 이는 프로토타입 체인의 단방향을 지키기 위해서다. 만약 직접 접근가능하다면, 서로가 서로의 프로토타입이 되면서 프로토타입 체인이 무한으로 돈다. 따라서 __proto__
프로퍼티로만 접근할 수 있다.
JavaScript는 class를 지원하지 않지만 생성자를 통해 class와 동일하게 사용 가능하다.
class 기반의 객체 지향 언어들은 모두 한 class에 속하는 여러 객체가 있을 수 있다.
이런 객체를 class의 instances라고 한다.
class property와 class method는 전역에서 접근 할 수 있다.
class method는 특정한 객체에서 작동하는 것이 아니여서 class를 통하는 함수라고 생각하면 된다.
이 둘은 JavaScript 네임스페이스에서 보호영역이 있어서 충돌을 방지한다.
class method를 정의하기 위해선 함수를 생성자 함수의 property로 만들면 된다.
참조