프로토타입이란?

콜라제로·2020년 7월 5일
0

자바스크립트

목록 보기
3/3

우선 넓은 개념을 한번 보자. 상속이란 개념은 반복적인 코드를 사용하지않고 재사용하는 것을 말한다. 이는 시간과 코드의 양등에 있어서 굉장히 효율적이다. 객체지향 언어는 상속에 따라 크게 2가지로 나뉠수있다.

  • 클래스 기반 언어: java, python, ruby, C++
  • 프로토타입 기반언어: Javascript

ECMA script 6이후에는 자바스크립트에서도 클래스를 사용할수 있지만, 프로토타입의 개념은 객체에서 객체를 바로 상속하는 의미에서 유래된다.

이제 자바스크립트식 객체 지향 프로그래밍에 대해서 알아보자.

생성자

객체를 생성 하는 함수를 생성자 함수라고 한다. 다른 언어에서는 class가 존재하지만, 자바스크립트에서는 생성자함수가 이를 대처한다. 코드로 예시를 한번 보자.

function Car(name, type){
  this.name = name;
  this.type = type;
  this.horn = function(){
    alert(this.name + ' is horning')';
  }
  ...
}

이 생성자 함수에는 몇가지 특징이있는데, 대문자로 시작하게 된다. 이게 규칙이다! 그러고 new라는 키워드를 통해서 자동차 객체를 생성할수있다. 예제를 보겠다.

var EQ90 = new Car('EQ90','sedan');//Car {name: 'EQ90', type:'sedan'}
EQ90.horn();//'EQ90 is horning'

생성자를 바탕으로 우리가 정의한 메소드와 프로퍼티등을 자유롭게 사용가능하다. (기존 클래스형식과 굉장히 비슷하다)

프로토타입

이제 위 예제에서 프로토타입을 통해 클래스형식의 상속을 해보겠다.

function Car(name, type){
  this.name = name;
  this.type = type;
}
Car.prototype.horn = function(){
  alert(this.name + ' is horning');
};

이렇게 생성된 생성자함수에 우리는 위에서 보았던 예제와 똑같은 코드를 작동시킬수있을까? 정답은 그렇다이다. 그러면 이제 이 2가지 방법중 어떠한 방법이 더 좋은지 혹은 왜 생겨났는지에 대해서 생각을 해봐야한다. 우선, 이 문제에 대해서 고민해보기 전에 프로토타입에 대한 좀 더 기술적인 의미에 대해서 알아보자.

일단 프로토타입이라는 뜻은 원형이라는 뜻이다. 생성자로부터 만들어진 객체(var EQ90 = new Car('EQ90', 'sedan'))은 결국 원형객체인 Car을 공유한다. 그래서 이 Car의 프로토타입객체에 horn이라는 메소드를 넣으면 Car생성자로 만든 모든 객체는 이 메소드 사용이 가능하다. 공유하고 있기 때문이다.

그렇다면 다시 이 전 문단으로 돌아가서 어떤것이 더 효율적일까? 정답은 후자이다. Car.prototype.horn에서는 모든객체가 공유하고있는 prototype에 한번만 메소드가 만들어지지만, this에 넣은것은 객체하나를 생성할때마다 메소드도 만들어지기 때문에 불필요한 낭비가 발생한다.

Prototype & _proto_

이제 조금더 prototype에 대해서 깊게 알아보는 시간을 가져보자. 우선, 생성자 함수를 통해 생성된 객체를 뜯어보면 굉장히 신기한 프로퍼티가 있다, 바로 _proto_이다.

var EQ90 = new Car('EQ90', 'sedan');
console.log(EQ90);

이때까지 다뤘던 것보다, 훨씬 복잡하다. 객체안에 _proto_는 또 무엇인가... 우선 프로토는 실제 객채를 만들 때 생성자의 prototype이 참조된 모습이다. 생성자의 프로토타입을 참조하기 때문에 _proto_와 prototype은 같다.

정리를 하자면 다음 포인트 들이 있다.

  • constructor는 생성자 함수 그 자체를 가리킨다.
  • prototype은 생성자 함수에 정의한 모든 객체가 공유할 원형
  • _proto_는 생성자 함수를 new로 호출할 때, 정의해두었던 prototype을 참조한 객체
  • prototype은 생성자 함수에 사용자가 직접 넣는 거고, _proto_는 new를 호출할 때 prototype을 참조하여 자동으로 만들어진다.
  • 생성자에는 prototype, 생성자로부터 만들어진 객체에는 _proto_
  • 따라서 사용자는 prototype만 신경쓰면 된다. _proto_는 prototype이 제대로 구현되었는지 확인용으로 사용한다.

이제 조금더 확실하게 이해가 간것같다. 위의 글들이 이해가 잘안간다면, prototype이 개발자입자에서 객체에 변화를 주기위해 access해야 될 것이고, _proto_는 생성자로부터 만들어진 객체가 prototype을 참조한 객체이다.

Prototype, _proto_와 constructor의 관계

prototype과 constructor는 부모자식 관계라고 생각하면 된다. 간단하게 위의 예제와 비교를 해보자면 이런 관계도가 성립할수있다.
Car.prototype === EQ90.__proto__;

Conclusion

아주 간단하게 prototype에 대해서 알아보았다. 하지만 프로토타입과 객체의 관게를 조금더 깊게 알아보기위해서 알아야될 다른개념들 prototype Link라던가 결과 적으로 어떤 부분을 어떻게 참조하게되는것인지에 대해서 좀더 다룰 필요가 있어보인다.

profile
frnontend

0개의 댓글