자바스크립트 - OOP

3 분 소요

매우 주관적인 포스트로서 사실과 다를수도 있습니다. 개인적인 정리 차원입니다.

오늘 내가 찾아볼것과 정리할것은 다음과 같다. ​

  1. OOP(Object Oriented Programming)가 무엇인지?
  2. JavaScript에서 Object를 생성하는 여러가지 방법들
  3. JavaScript에서 Prototype은 무엇이고 왜 사용해야 하는지? ​

OOP는 무엇일까?

강의를 듣던도중 마지막으로 알려주시던 말씀이 생각난다. OOP는 사람이 세계를 보고 이해하는 방법을 흉내낸 방법이다. ​ 이와 관련하여 우리는 핸드폰 내부가 어떻게 생겼는지, 자동차의 구조와 원리에 대하여 대부분은 관심을 가지지 않고 거리낌 없이 사용한다. 우리는 비슷한 물품, 생명체를 종속과목강문계 혹은 다른 관점에서 분류할수 있다. 또한 방금 태어난 생물은 부모의 형질을 가지고 있는것도 알고 있다. ​ 이를 컴퓨터 공학의 관점에서 본다면

  1. 우리는 유명한 API가 어떻게 동작하는지 모르고 간편하게 적용한다.
  2. 우리는 프로그래밍 언어를 작성하면 어떻게 기계어로 변환되어 실행되는지 관심없다.
  3. 우리는 비슷한 코드는 중첩하여 작성하지 않고 하나의 코드로 통합, 사용한다.
  4. 우리는 클래스를 상속받을때 이미 부모가 가지고 있던 것은 추가하지 않고 사용할수 있다.

좀더 디테일하게 설명하자면, 1,2 코드를 짤때 유용하게 사용되는 API는 모듈만 추가하여 간단하게 코드 한줄을 작성하여 사용하기도 한다. 이 때문에 이 API만 수정하면 내가 요긴하게 써먹을수 있지 않을까 하며 뜯어 보려고 했었다. 하지만 그 내부는 구현하기 힘든 코드들이 작성되어 있는 경우가 많았다. 이렇게 복잡한 내부는 가리고 비교적 심플한 외부분만 보여주어 자바스크립트에서 추상(Abstract)라 한다. 이는 C++에서 배웠던 추상하고는 거리가 살짝 있어 보인다. 내부 변수에 대하여 함부로 접근을 할수 없는점에서 캡슐화와 비슷하게도 보이기도? C++에서 추상은 주로 추상 클래스에서 사용했던 기억이 있는데, 이때 추상은 같은 이름으로 여러 객체에서 다르게 사용할수 있다는 점에서 자바스크립트에서의 폴리모피즘과 비슷해 보인다. ​3. 여러 프로그래밍 언어들은 기본적으로 중복되는 함수, 클래스, 구조체들은 따로 분류하여 호출을 가능하게 하고 있다. 이러면 일일히 다른 메모리 주소를 사용하지 않고, 같은 메모리 주소만 접근하게되므로, 매우 효율적이다. ​ 또한 ES6 자바스크립트 에서도 클래스를 사용할수 있는데, 이 클래스는 C++에서 사용했던 클래스와 유사한 경향을 발견할수 있었다. 둘다 생성자를 가지며, 자바스크립트는 js문법에 맞게 메소드를 추가하거나, C++는 함수를 추가하거나 할수 있다. 다만 C++의 public, private 변수, 함수 선언은 js에서는 조금 달라지는데, 생성자 내부에서 선언하여 클래스 자체를 this를 주면서 사용하면 클래스 내부에서만 접근 가능한 private 처럼 사용할수 있다. ​ 또한 이 클래스는 inheritance가 되어서, 이 클래스를 바탕으로 새로운 클래스를 만들어 내면, 기존 클래스가 가지고 있던 변수, 메소드 등과 새로이 만들어낸 것들을 같이 사용 가능한것 같다. 그리고 여기서의 super도 부모 클래스 여기저기 접근이 가능한것 같다. 부모 클래스의 생성자를 커스텀했으면 자식클래스 생성자에서 super로 부모 클래스 생성자를 호출해야 하는것도 동일하다.

// 참고: 파생 클래스에서 super() 함수가 먼저 호출되어야 // 'this' 키워드를 사용할 수 있습니다. 그렇지 않을 경우 참조오류가 발생합니다.

이거는 그냥 생성자에서 맨처음에 super로 원본 클래스의 생성자를 호출하면 되지 않을까 하는 생각이 든다. ​

JavaScript에서 Object를 생성하는 여러가지 방법들

  1. 평범하게 let 으로 변수에 obj를 생성한다.
  2. new 클래스로 새로운 클래스 혹은 객체를 생성한다. 이때 this를 이용하여 인스턴스를 재정의 할수 있다.
  3. function의 반환값으로 객체를 넘겨주거나, 변수에 객체를 담는다. ( 클래스던지, 객체 던지, functional shared 혹은 ptorotypal 혹은 pseudoclassical 이용) ​

JavaScript에서 Prototype은 무엇이고 왜 사용해야 하는지?

​ 여긴 아직도 헷갈린다. 하지만 조금이라도 정리해 보자. JS에서 프로토 타입은 함수들이라면 모두 가지고 있다. 하지만 실제 사용하는것은 proto와 Prototype 두가지이다. 우선 전자는 함수에서 상속 받게된 함수를 가리키고 있다. 그래서 mdn 에서는 ​

let f = function () {
  this.a = 1;
  this.b = 2;
};
let o = new f(); // {a: 1, b: 2}

이경우를 예제로 설명하고 있는데, O라는 변수(함수가 저장됨)에서 O.proto를 치면 상속 받게된 f를 가르키고 있다.

image 이때 보이는 f의 부모 함수는 Object 이다. 역시 Object에서 여러가지들을 상속 받은것을 확인할수 있었다. 그러면 proto 말고 Prototype은 무엇인가? 프로토 타입은 함수보다는 객체로 접근하는것이 편해보인다. ​ 우선 .prototype으로 접근하여, 자신이 해당되는것이 있다면 그것을 리턴시킨다. 하지만 그것이 없다면, 부모 펑션으로 올라가서 해당되는 것이 있는지 살펴본다. -> 상속을 받아서 생성되었기 때문에 가능하다. 부모 펑션에도 없으면 계속 찾아 올라간다.

//크롬 콘솔창에서 작성, 위 에서 계속
f.prototype.b = 3;
f.prototype.c = 4;

o.__proto__
{b: 3, c: 4, constructor: ƒ}
o.b // 2 f 의 상위 함수에 b의 값으로 3이 저장된다. 우선순위로 o에는 b값이 2로 저장된것이 발견되어 2 가 리턴된다.
o.c // 4 f 의 상위 함수에 처음 발견되며 그값이 4이다.
o.d // 최상위 함수에도 존재하지 않아 결국에는 null까지 올라가 본다.

그러므로, 이전에 설명한 클래스가 사용되기 이전부터 지금까지 계속 상속된 객체처럼 사용되던 방법이였으며, 함수를 오버로딩하여 입맛대로 바꿔서 사용이 쉬워 사랑받았던 방법인것 같다. JS가 프로토 타입 기반이라고 하는 이유가 여기 있다.

댓글남기기