프로토 타입 기반 프로그래밍은 객체지향 프로그래밍의 한 형태로 클래스가 없고, 클래스 기반 언어에서 상속을 사용하는 것과는 다르게 객체를 원형으로 하여 복제(상속) 과정을 통해서 객체의 동작 방식을 다시 사용할수있다. 프로토타입 기반 프로그래밍은 클래스 리스 , 프로토타입 지향 , 혹은 인스턴스 기반 프로그래밍이라고도 한다. - 위키 백과 인용 -
자바스크립트의 모든 객체는 자신의 부모를 가리키는 참조링크인 [[Prototype]] 링크를 가지고 있다.
아래의 예시를 보자.
const tanni = {// 타니는 우리집 개이름이다.
fat : true
}
tanni.fat ==> true
tanni.slim ==> undefined
이 코드를 입력하면 true가 뜨는건 기초를 배우면 다 아는 사실이다. 그러나 원리를 보자면 tanni.fat 입력하면 true가 뜨는 것처럼 객체의 프로퍼티를 참조 할 경우 [[get]]호출되어 객체 내부에 해당 프로퍼티가 있는지 확인한다.
그러나 그 내부에 해당하는 프로퍼티가 없다면 어떻게 할까? 그 [[get]]은 [[Prototype]]타고 올라가 또 프로퍼티를 탐색한다. 그러다가 그래도 없다면 undefined를 반환한다. 참고로 최상위 프로토타입 내장 Object.prototype 이다.
그러나 한가지 방법이 있다. Object.create() 메서드를 사용하면 임의로 그 포로토 타입 객체를 링크 할 수 있다.
const tanni = {// 타니는 우리집 개이름이다.
fat : true
}
const mengyi = Object.create(tanni) // 멍이도 우리집 개이름이다.
mengyi.fat ==> true
이 메소드를 사용하므로서 탄이와 멍이는 [[Prototype]]이 링크가 된것이고 멍이 내부에는 fat이라는 프로퍼티가 없지만 [[get]]이 타고 올라가 탄이를 찾았고 해당 프로퍼티를 찾아 그 값을 출력한 것이다.
다시 실생활에 적용되는 말로 표현하자면 탄이가 원래 돼지 였던놈인데 멍이도 같은 주인 [[Prototype]] 으로 인해 나고 먹고자라 같이 돼지가 된 것이다.
항상 클래스 함수에 대해서 궁금하고 수박 겉핣기식으로 해온 감이 있어 이번 기회에 정리 할까 한다.
const ourDogs = function(){}
그냥 함수를 정의 하면 원형을 알아 보면 위와 같다. 구조인 constructor와 __proto__
를 가지고 있다.
- constructor는 내가 선언한 함수를 지칭하며 그 이름은 ourDogs다. 인스턴스를 형성 할땐 new 키워드와 같이 쓴다.
es5
const OurDogs = function(name){
this.name = name;
this.father = 'me';
}
let dog1 = new OurDogs('tanni');
let dog2 = new OurDogs('mengyi')
//---------- 출력 값
input : dog1
OurDogs {name: "tanni", father: "me"}
input : dog2
OurDogs {name: "mengyi", father: "me"}
es6
class Ourdogs {
constructor(name){
this.name = name;
this.father = 'me'
}
}
let dog1 = new OurDogs('tanni');
let dog2 = new OurDogs('mengyi');
//---------- 출력 값
input : dog1
OurDogs {name: "tanni", father: "me"}
input : dog2
OurDogs {name: "mengyi", father: "me"}
이렇듯 new 연산자는 클래스로 부터 작동을 복사하여 새로운 객체를 만드는 것이다. 또 Object. create() 라는 메소드를 이용해 직접적으로 객체를 연결해주는 방법도 있다. 차이는 이 포스팅을 참조하면 된다.
- prototype 은 함수에 정의 한 모든 객체가 공유할 원형인것이다.
그러니까 우리 개들이랑 탄이 한놈이랑 부모(원형)가 같다는 것이다.
Ourdogs.prototype === Object.getPrototypeOf(dog1)
true
Ourdogs.prototype === Object.getPrototypeOf(dog2)
true
__proto__
는 [[Prototype]] 링크이다. 함수에 정의해 두었던 prototype을 참조한다.
부트캠프를 진행하면서 연산자 생성자라는 단어가 좀 혼동이 있었는데 단어가 중요하겠냐만은 의미를 파악하는 좋은 사고 인것 같아 인터넷을 좀 찾아 보았다.
정리하자면 위에서 보았던 es5나 es6 클래스 함수는 그저 함수이다.
typeof Ourdogs
"function"
콘솔에 찍어보니 그저 함수일 뿐이고 js에서 new 붙여 호출한 함수를 모두 생성자라고 한다. 함수에 new를 붙여서 호출하면 생성자 호출이 되는것이다.