이번에는 자바스크립트 객체 지향 프로그래밍(OOP)에 대해 알아보겠습니다.
객체 지향 언어에는 다양한 종류의 언어들이 있습니다. 이 객체 지향 언어들은 대부분 Class 기반 언어로 Class가 존재합니다. 자바스크립트도 ES6이후 Class가 추가 되었지만 클래스 기반 언어가 된것은 아닌 여전히 프로토타입 기반 언어입니다.
그러면 자바스크립트의 OOP 키워드들에 대해서 알아보겠습니다.
자바스크립트에는 본래 상속이라는 개념이 존재하지 않습니다. 하지만 우리는 함수와 new라는 친구 덕분에 상속의 기능을 비슷하게 흉내낼수 있습니다. 바로 예시를 통해 알아볼까요?
function labtop(){
this.keyboard = "keyboard";
this.display = "display";
}
const mac = new labtop();
const gram = new labtop();
console.log(mac.keyboard); //keyboard
console.log(gram.keybard); //keyboard
위의 코드를 보면 mac과 gram은 모두 keyboard와 display라는 요소를 갖고있습니다. 이렇게 laptop이라는 함수를 통해 mac과 gram이라는 새로운 인스턴스를 만들수 있습니다. 이 인스턴스들은 노트북이 가져야하는 요소를 갖게되었습니다. 하지만 이렇게 생성한다면, 새로운 노트북이 나올때마다 keyboard와 display요소를 메모리에 할당해 줘야하기 때문에 100개의 노트북이 생기면 200개의 변수가 메모리에 생기게 됩니다. 하지만 prototype을 이용하면 이러한 문제를 해결할수 있습니다.
function labtop(){}
labtop.prototype.keyboard = "keyboard";
laptop.prototype.display = "display"
const mac = new labtop();
const gram = new labtop();
console.log(mac.keyboard); //keyboard
console.log(gram.keybard); //keyboard
이전 코드와 차이점을 아시겠나요? prototype을 사용하면 labtop.prototype이라는 Object에 요소를 추가할수 있으며, laptop을 통해 만들어진 인스턴스는 labtop.prototype에 존재하는 프로퍼티를 가져와 사용할수 있습니다. 다시말해 mac과 gram은 개별적으로 keyboard와 display를 갖는것이 아닌 labtop.prototype에 존재하는 keyboard와 display를 공유해서 사용하는 것입니다.
자 이번에는 __proto__라는 친구에 대해 알아보겠습니다.
우리가 어떠한 객체를 만들었을때 그 객체는 보이지는 않지만 __proto__라는 프로퍼티를 갖게됩니다. 이 프로퍼티에는 객체가 생성될때 부모였던 함수의 prototype object를 가리키게 됩니다. 이전 코드를 다시 살펴보겠습니다.
function labtop(){}
labtop.prototype.keyboard = "keyboard";
laptop.prototype.display = "display"
const mac = new labtop();
const gram = new labtop();
console.log(mac.keyboard); //keyboard
console.log(gram.keybard); //keyboard
이 코드에서 mac.__proto__는 labtop.prototype객체를 가리키고 이 labtop.prototype 객체 또한 __proto__ 프로퍼티를 갖고 있어 결국 labtop()함수를 가리키게 됩니다.
코드를 통해 예시를 들어보겠습니다.
kim = {
a: 1,
b: 2,
sum: function(){
return this.a + this.b;
}
}
lee = {
a: 2,
b: 3
}
lee.__proto__ = kim;
console.log(lee.sum()); //5
이해가 되시나요? kim은 sum이라는 함수를 갖고있지만 lee는 갖고있지 않습니다. 그럼에도 lee 가 sum을 할수 있는 이유는 lee의 __proto__에 kim을 할당에 주었기 때문입니다.
console.log(lee.sum()); //5
이 부분을 실행하게 되면 lee는 우선 자신에게 sum()이라는 함수가 있는지 확인해보고 없다면 자신의 __proto__에 담긴 kim에게 sum()이라는 함수가 있는지 확인합니다.
이러한 과정을 통해 lee 또한 sum()을 사용할수 있게됩니다.
constructor는 생성자 라고 불립니다. 이 constructor는 인스턴스가 생성될때 실행되는 함수를의미합니다. 좀 전에 살펴본 내용을 보면 우리가 함수를 선언했을때 그 함수를 상속받아 새로운 인스턴스를 생성한다면, 그 인스턴스는 상속받은 함수의 prototype object를 참조한다고 했습니다. 다시말해, 인스턴스를 생성할때 실제 우리는 prototype object를 참조하는데, 이때 받아오는 내용은 constructor에 있는 내용이라고 할수 있습니다.