프로토타입을 알아보기전에 생성자 함수를 짚고 넘어가도록 하겠습니다.
생성자함수의 프로토타입과 내부메소드는 전혀 다른 것입니다.
자바스크립트는 "생성자함수" 를 이용해 객체를 만들어 낼 수 있습니다. (유일한 방법은 아닙니다.)
이렇게 생성자함수에 의해서 생성된 객체를 "인스턴스"라고 합니다.
생성자 함수와 일반 함수에 기술적인 차이점은 없습니다. 다만, 지켜주어야하는 형식이 있는데 이 형식으로 구분하곤합니다.
생성자 함수는 왜 사용하는 것일까요? 정답은 재사용성에 있습니다.
생성자 함수는 객체를 만들어낸다고 했습니다. 아래와 같이 객체리터럴로 1억개를 만들어야 하는 상황이 온다면 어떨까요? 끔찍하죠..?const a = {x:"x", y:"y" ...}
자, 그럼 생성자 함수가 어떻게 객체를 생성해 내는지 알아볼까요?
생성자 함수의 형태
function Constructor (pram1,pram2,...) { this.el = pram1; this.el2 = pram2; ... } const item = new Constructor("김태형","31");위의 생성자 함수를 사용하면 내부적으로 어떻게 동작하는지 알아보겠습니다.
function Constructor (pram1,pram2,...) { //this는 새로 만들어질 인스턴스를 가르킵니다. 지금 상황에선 item 이겠죠? this.el = pram1; //새로 만들어질 인스턴스의 속성입니다. ( 매개변수 이용 ) this.el2 = pram2;//속성을 하나도 만들지 않으면 빈 객체가 반환됩니다. } //return { // el:pram1, // el2:parm2 // } // return 문은 이해하기 쉽도록 내부적으로 어떻게 작동되는것인가를 상상해봤습니다. const item = new Constructor("김태형","31"); // new연산자를 이용한 호출은 아래 객체를 사용한것과 같은 동작을 하게됩니다. // 매개변수로 받은 값을 this를 이용해 인스턴스 객체에 속성 값을 할당하고 그 객체를 리턴해주는 방식 같습니다. const item = { el : "김태형", el2 : "31" }
여기까지 생성자 함수에 대해 알아봤습니다.
JavaScript는 다른 객체지향 언어와는 다르게 클래스라는 개념이 없습니다. 그래서 클래스대신 프로토타입이라는 기술을 통해 객체지향을 추구했는데요.
JavaScript의 모든 객체는 프로토타입이라는 객체를 가지고있습니다. 모든 객체는 생성자의 프로토타입으로부터 프로퍼티와 메소드를 상속받습니다.
constructor - 부모, prototype - 부모의속성과 메소드
[[prototype]] - 자식이 상속받은 속성과 메소드
위와같은 방법으로 JavaScript는 객체지향을 구현했습니다
생성자에 프로토타입에 정의된 속성과 메소드는 생성자로부터 생성된 모든 인스턴스들이 공통적으로 가지고 있습니다.
위에 생성자 함수 파트에서 설명했듯이 프로토타입도 재사용성에 포커스를 맞추면됩니다. 바로 메모리효율의 극대화 입니다.
중요! ⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
생성자함수의 내부에 정의된 내부함수는 생성된 인스턴스들이 각자 자신만의 고유한 함수를 가지게됩니다. 각각 다른 메모리에 적재된다는 말입니다.반면에 생성자함수의 프로토타입에 정의된 메소드는 단 하나만 존재하며 생성된 인스턴스들이 참조할 수 있습니다.
예를들어, 엄마와 아들 둘이 있습니다.
생성자함수의 내부 메소드는 " 얘들아 가위 하나씩 줄테니까 종이를 자르던 과자를 자르던 알아서해 "
생성자함수의 프로토타입 메소드는 " 얘들아 가위 엄마가 가지고 있을테니까, 필요할때 말해 "
의 차이인 것입니다.메소드를 가진 주체가 누군지가 명확히 달라지는 것이죠.
function constructorFunc(){ this.func = function(){ console.log("내부함수"); }; constructorFunc.prototype.func2 = function(){ console.log("프로토타입"); }; } const v1 = new constructorFunc(); const v2 = new constructorFunc(); console.log(v1.func === v2.func); //false console.log(v1.func2 === v2.func2 ); //true
![]() | ![]() |
|---|---|
| 1. 생성자 함수는 prototype 속성을 가지고있습니다. 2. 인스턴스는 [[prototype]] 속성을 가지고있습니다. 3. 인스턴스의 [[prototype]] 속성을 통해 생성자 함수의 속성과 메소드를 전달 받습니다. | 좌측 설명의 결과로 위 그림을 생각해주시면 되겠습니다. |
[[prototype]] 속성은 상속받은 속성과 메소드를 콘솔창에 보여주기만할 뿐 접근하는 방법은 따로 있습니다. 아래에서 다루어 보겠습니다.
instance.[[prototype]].prototype <- 불가능합니다.
배열을 예시로 들어서 보자면, 배열 생성자의 prototype 에는 배열 메소드들이 들어있고, 새로 만들어진 배열은 생성자에의해서 [[prototype]] 속성에 메소드들을 상속받는 개념입니다.
![]() | ![]() |
|---|---|
| 배열 생성자의 prototype | 생성된 배열인스턴스의 [[prototype]] |
null, undifined 제외
원시타입 데이터같은 경우에 .을 이용해 메서드에 접근하려하면 임시로 문자열의 인스턴스를 만들어서 메서드를 실행하고 결과를 얻음과 동시에 인스턴스를 폐기합니다.

원시타입 데이터를 제외한 모든 객체들은 위와같은 과정을 할 필요없이 모두 기본적으로 프로토타입을 가지고있습니다^^
프로토타입에 접근하는 방식은 크게 두가지가 있습니다.
아래 예시를 보겠습니다.
아래 예시는 생성자의 프로토타입 속성까지 접근하는 방법입니다.
단순히 생성자까지 접근을 원하신다면 .constructor 에서 멈추시면 됩니다.
function Person(n,a){
this.name = n;
this.age = a;
this.func = function(){ console.log("함수") }
}
const firstPerson = new Person("태형",31);
생성자를 이용한 prototype 접근법
- Person.prototype
- 생성자.prototype
인스턴스를 이용한 생성자 prototype 접근법
- firstPerson.constructor.prototype
- 인스턴스.constructor.prototype
- Object.getPrototypeOf(firstPerson).constructor.prototype
- Object.getPrototypeOf(인스턴스).constructor.prototype
- firstPerson.__proto__
- 인스턴스.__proto__.
생성자의 프로토타입의 속성과 메소드는 동적으로 추가할 수 있다.
- Person.prototype.setOlder = function(){ this.age +=1; }
- Person.prototype.getAge = function(){ return this.age; }

생성자의 프로토타입 속성 또한 객체이므로 상위 프로토타입에서부터 상속을 받습니다.
언제나 최상위 객체에는 Object 가 있으며 자바스크립트 전체를 통괄하는 공통된 메서드들이 있습니다.
인간세상에 대입해보면 최상위 조상이 Object 라고 생각하시면 좋을거같습니다.
그러므로 발생하는 문제가 Object 생성자의 프로토타입에는 메서드를 정의할수가 없었습니다.
만약, 값을 반환해주는 메서드를 프로토타입에 만들었두었다고 가정하면 모든 데이터타입에 적용할수가 없기때문입니다.
그래서 프로토타입이 아닌 생성자함수에 메서드로 정의할수밖에 없었습니다.
유독 객체에 관련된 명령어들은 직접 메서드를 호출하는 대신에 Object. 으로 시작는 명령어가 많지 않았나요??
생성자 함수에 접근하여 매개변수를 넘겨주는 방식을 채택한것입니다.


프로토타입 체이닝도 스코프 체이닝처럼 본인의 생성자함수에서 먼저 찾아보고 없으면 프로토타입을 타고 올라가면서 찾습니다.
정리
1. 자바스크립트는 프로토타입 방식으로 객체지향을 구현했다.
2. 모든 객체는 프로로타입을 가지고있다.
3. 생성자함수에의해 객체를 생성하면 [[prototype]] 에 생성자 함수에서 상속받은 내용이 들어있고 사용할 수 있다.
4. 원시타입 데이터에서 메서드를 사용하려하면 해당 타입의 객체가 잠시 생성되어 연산이 끝나면 다시 제거된다.
5. 프로토타입도 스코프체인처럼 체이닝이 가능하며 언제나 최상위는 object 이다.
6. 생성자함수의 속성과 메소드는 동적으로 추가할 수 있다.