JavaScript
는 Prototype
기반 언어라고 불린다. 전에도 Prototype
에 대해서 학습을 해왔고, 나름 대충 이해한 상태로 넘어왔었다. 그러나 지금와서 다시 Prototype
을 보면 잘 기억도 안나고, 뭐라 하는지도 모르겠다.
아무튼 중요한건 JavaScript
는 Prototype
기반 언어이다. 즉 Prototype
는 자바스크립트의 핵심이며 기초이다.. 그 기초를 제대로 알아야 언어를 다루는데 유리하다고 생각한다.
프로토타입 기반 프로그래밍
은 객체지향 프로그래밍의 한 형태이다.
Class
를 사용하는 객체지향 언어들은 Class
안에 기술된 내용을 기반으로 인스턴스를 생성하여 객체를 사용한다. JavaScript
는 객체지향 언어라고 하지만 Prototype
을 기반으로한다. Prototype
을 활용해 상속 및 확장해 나가는 방식으로 새로운 객체를 생성해낸다. ES5
이후로 Class
를 사용하여 표현하는데 원형이 Class
기반으로 바뀌는게 아니라 문법만 바뀐것이다.
Class보다 더 적은 메모리를 사용한다.
Prototype
의 장점 인데 Class
기반보다 메모리를 보다 덜 사용한다.
VrGear
라는 청사진이 존재한다. 이 청사진을 기반으로 한 제품은 공통된 기능이 반드시 있어야하며, 추가적으로 만들 제품 또한 역시 같은기능을 포함시켜야한다.
function VrGear() {
this.hello = function(){ console.log("I'am A")};
this.introduce = function(){ console.log("I'am B")};
}
let Quest2 = new VrGear();
let Vive = new VrGear();
console.log(Quest2);
console.log(Vive);
보이는 바와 같이 hello
와 introduce
기능 모두 각각의 제품에 할당되었다. 그러면 개수가 총 4개! 4개의 변수가 메모리에 할당됐다.
제품을 계속 출시한다면, 예를들어 Lift S
, Reverb
등을 계속해서 추가할 때마다 2개씩 늘어나면 서 메모리도 비례하여 공간을 차지하게된다.
이런 문제를 Prototype
으로 해결할 수 있다.
//VrGear이라는 원형 청사진을 만든다.
function VrGear() {}
VrGear.prototype.handTracking = function(){console.log("possible?")};
VrGear.prototype.frequency = function() {
const hertz =[60, 120, 144];
for(let hz of hertz){
console.log(`${hz}hz`)
}
};
let Quest2 = new VrGear();
let Vive = new VrGear();
console.log(Quest2);
console.log(Vive);
쉽게 보면,VrGear.prototype
이라는 어딘가에 존재하는 빈 객체에다가, 몇 가지 기능을 추가하고, 만든 제품 Quest2
와 Vive
는 어딘가에 존재하는 객체에 들어있는 기능(속성)을 가져와 사용하고 있다.
결국, 두 제품 모두 같은 기능을 어딘가에 존재하는 곳에서 속성을 공유받아 사용한다 라고 해석이된다.
그러면 왜 이게 가능한지 자세히 알아보자.
자바스크립트에서 Prototype Link
와 Prototype Object
라는 것이 존재하고, 이 둘을 통틀어 Prototype
이라고 부른다.
Prototype
을 좀더 쉽게 이해하기 위해서 많이 참고하여 몇가지로 나누어 작성을 했다다. 정리된 내용을 보고 Prototype
을 이해해보자!!
다시말하자면 객체
는 언제나 함수(Function)
로 생성된다.
function A() {} //함수
let func = new A(); //func는 함수로 객체 생성
let arr = [];
let obj = {};
func
는 함수 A()
로 생성된 단일 객체이다.
arr
와 obj
도 사실은 함수를 가져다가 생성한 것이다.
let arr = new Array();
let obj = new Object();
arr
, obj
모두 자바스크립트에서 기본으로 제공하는 함수이기 때문에, 모든 객체는 함수에서 시작된다.
모든 타입을 일일히 찍어보면 모두 함수로 출력된다.
undefined
,null
빼고..
Constructor
자격이 부여되면 new
키워드를 통해 객체를 만들 수 있다.
위 이미지처럼 접근했다간 구글 크롬 형님이 자격이 없다고 퇴짜놓는다.
결국 모든 함수는 Constructor
를 가지게 된다. 그래서 함수만 new
를 사용할 수 있다.
VrGear
라는 함수를 정의했다. 함수를 정의하면 자신을 정의함과 동시에 Prototype Object
라는 복사본도 생성이되는데. __proto__
와 Constructor
자격을 기본으로 가지게 된다.
Constructor
은 자신의 원본을 가르키며, prototype
은 복사본을 가르키고 있다.
이제 개발자는 제품을 설계하는데 있어, 공통 기능을 추가해주려고 한다.
Prototype Object
는 일반 객체이기 때문에, 복사본에 기능을 추가하기 위해서는 prototype
이라는 속성을 통해서 접근할 수 있다.
이제 방법을 알았으니 개발자는 원하는 기능을 추가하거나 지울 수 있게되었다.
VrGear.prototype.handTracking = function(){console.log("possible?")};
VrGear.prototype.frequency = function() {
const hertz =[60, 120, 144];
for(let hz of hertz){
console.log(`${hz}hz`)
}
};
let Quest2 = new VrGear();
let Vive = new VrGear();
__proto__
부분을 보다가 Assassin's Creed
라는 게임이 떠올랐다. 왜 이놈이 조상을 가르키는 족보이며 열쇠라는 것일까?
위에서 어떤 개발자는 VrGear라는 원본이 복제된 청사진을 가져다가 공통으로 적용할 기능을 추가하여 각 제품 모두 사용할 수 있게 적용했다. 그러나 Vive
와 Quest2
내부에는 이 기능이 존재하지 않는다. Prototype Object
이라는 곳에 존재하는 기능을 참조하여 사용하는데, 어떻게 참조해오는지 반드시 알아야할 필요가 있다.
그 존재는 바로 각 모든 객체가 가지고있는__proto__
속성이자 열쇠이다.
해당 기능들은 복사본인 VrGear.prototype
에 존재했다는것을 알게되었다.
만약, VrGear.prototype
에도 없다고 가정하면 __proto__
속성으로 해당 기능을 찾을 때 까지 탐색을 해나가며 최상위 Object
의 Prototype Object
에 도달하게된다. 그럼에도 못찾을 경우에는 우리가 흔히 보는 undefined
나 TypeError
를 구경할 수 있게된다.
이렇게 최상위로부터 최하위 객체까지 정보를 공유하고, 최하위 객체는 __proto__
속성을 통해 최상위까지 이어져있는 이 연결고리를 Prototype Chain
이라고 한다.
다시는 잊지말자