27일차 객체 지향 프로그램, 자바스크립트의 Prototype이란 ?

1-1. 객체 지향 프로그래밍( OOP : Object Oriented Programming) : 프로그래밍에서 필요한 데이터를 추상화 시켜 상태와 행위를 가진 객체를 만들고 그 객체들 간의 유기적인 상호작용을 통해 로직을 구성하는 프로그래밍 방법이다.

데이터와 기능이 별개로 취급되지 않고 한 번에 묶어서 처리될 수 있는 장점이 있다 객체지향 프로그래밍을 이해하기 앞서 클래스와 인스턴스를 알아야 한다. 아래 예시를 살펴보자!

  • 클래스 : 세부사항(속성)이 들어가지 않은 청사진 ex ) 붕어빵 틀
  • 인스턴스 : 클래스에 세부사항이 들어간 것 ex ) 붕어빵 틀로 만들어진 붕어빵

  • 객체 ➰ 인스턴스 => new 키워드를 써서 만든다. 즉시 생성자 함수가 실행되며 변수에 클래스 설계를 꼭 닮은 새로운 객체, 즉 인스턴스가 할당된다.
  • 클래스 만들때 : class Car { constructor(brand, name, color }
  • 위 함수는 생성자 (constructor) 함수라고 부른다. 인스턴스가 만들어질때 실행되는 코드이다.

1-2. 객체지향 프로그래밍은 일상생활의 모델을 코드로 옮기는데 유리하다. 아래 예시를 살펴보자.

나는 선생님이고, 학교에 있는 학생들에게 청소를 시켜야 하는 일을 한다고 가정하자. 아이들에게 한 명 씩, 너는 101호에 가서 창문을 닦고, 너는 102호에 가서 칠판을 닦고 …. 등의 명령을 내리는 것은 비 효율적이다. 심지어 업무 및 청소 장소를 할당하고 나서도 그 이후…깨끗이 청소 되었는지, 청소 물품은 충분한지 등 계속 follow-up을 해줘야 하는 것이다. 합리적으로 업무를 하기 위해 데이터와 기능이 클래스로 캡슐화(encapsulation : 속성이나 기능을 따로 정의하는 것이 아닌 하나의 객체 안에서 묶는것) 된 객체로 업무를 할당한다.

부모 클래스를 청소라고 가정하자. 이에 청소에 인터페이스(상속은 물려 받은것, 인터페이스는 장착된 것)를 적용한 클래스인 창문닦기, 바닦쓸기, 칠판 닦기 등 자식 클래스를 만든다. 이를 상속(inheritance : 부모 클래스의 특징을 자식 클래스가 물려 받는것) 이라 한다.

하지만 청소 장소가 교실만 있는 것은 아닐것이다. 음악실, 과학실, 컴퓨터실 청소가 필요한데, 이때마다 클래스를 만드는 것은 역시 비효율적이다. 여기서 사용할 수 있는 개념은 다형성(polymorphism : 객체역시 똑같은 메소드라 하더라도 다른 방식으로 구현될 수 있는것) 이다. 청소라는 클래스는 상속 받았으나, 부모 클래스에서 정의된 메소드 작업이 자식 클래스에서는 다른 것으로 대체될 수 있는 것이다.

또한 청소가 진행되고 있는데 선생님이 학생의 청소에 관여하는것은 업무 혼선을 초래한다. 때문에 추상화(abstraction : 내부 구현은 아주 복잡한데, 실제로 노출되는 부분은 단순하게 만드는 것) 이 필요하다. 노출된 단순한 부분 만을 수정해서 업무 효율성을 증대하는 것이다.

출처 : https://www.youtube.com/watch?v=vrhIxBWSJ04

1-3 객체지향 프로그래밍의 장점

  • 코드 재사용이 편하다
  • 유지보수가 쉽다
  • 대형 프로젝트에 적합하다.

1-4 객체지향 프로그래밍의 단점

  • 처리속도가 느리다.
  • 설계시 많은 시간과 노력이 필요하다.

2. Prototype 이란 ?

  • 자바스크립트는 프로토타입 기반 객체 지향 프로그래밍 언어이다.
  • 자바스크립트의 모든 객체는 자신의 부모 역할을 담당하는 객체와 연결 되어 있다. 이것은 마치 객체 지향의 상속 개념과 같이 부모 객체의 프로퍼티 또는 메소드를 상속받아 사용할 수 있게 한다.
  • 이러한 부모 객체를 Prototype(프토로타팁) 객체 또는 줄여서 Prototype (프로토타입)이라 한다.
  • Prototype 객체는 생성자 함수에 의해 생성된 각자의 객체에 공유 프로퍼티를 제공하기 위해 사용한다.
function Person() {}
Person.prototype.eyes = 2;
Person.prototype.nose = 1;

let kim = new Person();
let Cheong = new Person();

console.log(Cheong.eyes); //=> 2

Person.prototype 이라는 비어있는 object가 어딘가에 존재하고 , Person 함수로 부터 생성된 객체( kim , Cheong) 들은 어딘가에 존재하는 Object에 들어있는 값을 모두 갖다 쓸 수 있다. 즉 eyes, nose 를 어딘가에 있는 빈 공간에 넣어놓고 kim, Cheong이 공유해서 사용하는 것이다.

  • 함수를 정의하면 함수만 생성되는 것이 아니라 Prototype Object 도 같이 생성된다.
  • 그리고 생성된 함수는 prototype 이라는 속성을 통해 Prototype Object 에 접근할 수 있다. Prototype Object는 일반적인 객체와 같으며, 기본적인 속성으로 constructor 와 __proto__를 가지고 있다.
스크린샷 2021-04-09 오후 1 42 30
  • constructor는 Prototype Object와 같이 생성되었던 함수를 가리키고 있다.
  • __proto__는 Prototype Link이다.
스크린샷 2021-04-09 오후 1 45 11
스크린샷 2021-04-09 오후 1 45 18

Person.prototype 객체에 eyes와 nose 속성이 추가 되었다. Prototype Object 는 일반적인 객체이므로 속성을 마음대로 추가/삭제 할 수 있다. kim, Cheong은 함수 Person 을 통해 생성 되었으니 Person.prototype을 참조할 수 있게 된다.

  • Cheong 에는 eyes 라는 속성이 없는데도 Cheong.eyes를 실행하면 2라는 값을 참조 한다. 이것은 __proto__ 의 기능이다.
  • __proto__ 는 객체가 생성 될 떄 조상이었던 함수의 Prototype Object 를 가리킨다. Cheong 객체는 함수 Person으로부터 생성 되었으니 함수 Person의 Prototype Object를 가리키고 있다.
  • Cheong 객체가 eyes 를 직접 가지고 있지 않기 떄문에 eyes 속성을 찾을 떄 까지 상위 프로토 타입을 탐색한다.
  • 최 상위인 Object 의 Prototype Object 까지 도달했는데도 못찾았을 경우 undefined 를 리턴한다.
  • 이렇게 __proto__ 속성을 통해 상위 프로토타입과 연결되어있는 형태를 Prototype Chain 이라고 한다.
  • 이런 프로토타입 체인 구조 때문에 모든 객체는 Object의 자식이라고 불리고 Object Prototype Object 에 있는 모든 속성을 사용할 수 있다.

Updated: