Prototype vs this

조 은길·2021년 11월 11일
1

Javascript 정리

목록 보기
13/48
post-thumbnail
post-custom-banner

오늘은 Prototype이 얼마나 유용한지에 대해서 알아보자!!

  • JS는 프로토타입에 기반한 언어이다.
    즉, 모든 property와 method가 이미 존재하는 prototype에서 왔다.
    우리가 객체를 만들 때, 객체는 a master constructor (고유한 method들을 가지고 있는)으로부터 만들어졌다.

  • 그렇다면, 왜 JS는 이런 방식으로 만들어졌을까??
    간단하게, memory efficient 때문이다.

만약에 우리가 무언가를 만들려고 한다면, 만들고자 하는 것의 청사진(blueprint)부터 만들 것이다. 여기서 청사진은 constructor function이라고 할 수있다. 그리고 이 청사진으로부터 많은 instances들을 만들수 있다. 다른 말로 하자면, constructor functions은 objects를 만들기 위한 견본이다.

그리고 개발자는 constructor function을 만들 때, 사용할 properties와 methods를 정의해야 한다.

이것은 2가지 방식으로 가능한데, 바로 this 키워드를 사용하거나 혹은 “prototype” property를 사용해서이다.


1. This를 사용해서 constructor를 정의하기

고객들의 주문을 불러내는 FoodOrder라는 class를 만들어보자!


만약, this를 이용해서 class를 만든다면, 해당 class를 통해서 만들어지는 모든 instance들은 ( order1, order2 ) 각자 고유한 foodOrder의 properties와 methods의 copy를 가지게 될 것이다.
즉, instance가 찍힐 때마다, foodOrder의 속성들이 복사되기 때문에, 메모리 낭비로 이어진다.

각 instance들을 console을 통해서 확인해보자!!

문제점이 보이는가??
각 instance는 고유한 callOrder() 메소드를 가지고 있다. 이렇게 instance가 새로 생길 때마다 callOrder()가 복제되면, instance의 숫자가 늘어날수록 퍼포먼스를 느리고 하고 메모리를 상당히 잡아먹는다.

만약에, 직관적으로 callOrder()가 각 인스턴스마다 고유한지 보이지 않는다면, 어떻게 확인할 수 있을 까?? 좀 더 확실한 확인법이 있을까??

방법은 간단한다. 둘을 이렇게 비교해보면, 된다.

그래서, 여기에 대한 해결책은 있는가??

물론있죠!!
바로 prototype을 사용하는 것이다.


2. Prototype 사용하기

Prototype을 사용하는 것은 다음과 같은 장점이 있다.

  1. 만약에 당신이 FoodOrder.prototype를 이용해서 property를 추가한다면, 해당 property는 FoodOrder class를 통해 만들어진 그리고 미래에 만들어질 모든 객체들에게 공유된다.
    => property를 공유하는 것은 property를 복제하는 것과는 다른 개념이다.

  2. Prototype을 사용해서 property value를 변경하면, Prototype chain에 의해서 연결되있는 모든 객체들의 해당 value 역시 바뀌게 된다.

  3. 대부분의 경우, prototype을 사용하면, 얼마나 많은 객체를 찍어내더라도, 오직 단 한 개의 FoodOrder instance만을 가진다. 즉, 객체마다 고유한 카피를 갖지 않는다. 그래서, prototype은 this 방식보다 메모리를 훨씬 절약하게 해준다.

이제 위에서 사용한 예시를 아래와 같이 바꿔보자.

  • constructor내의 this.callOrder을 지우고, prototype을 사용하는 방식으로 바꿨다.

그런데 왜 여전히 this.name과 this.food를 사용해야 될까??

각 주문은 유니크한 이름과 음식을 같는다. 그렇기 때문에, this를 사용해서 고유한 값을 만들어 둘 필요가 있다. => 즉, name과 food는 인스턴스가 생성될 때마다 복제됨!!

그러나, callOrder()는 전혀 다른 얘기이다.
모든 주문들이 같은 방식으로 불려진다. 그렇다면, 왜 구지 이것까지 각각의 FoodOrder에 복제를 해야 되나??

그럴 필요가 없다.

이번에도 각 instance들을 console을 통해서 확인해보자!!

위의 그림은 callOrder()를 부를 때마다, 각 인스턴스들은 FoodOrder의 callOrder()를 복제하지 않았다는 말이다. 왜냐하면, 우리가 prototype을 사용했기 때문에, 복사할 수없다.

좀 더 확실하게 복사가 됐는지 안 됐는지 증명하기 위해서, 확인해보자!


=> order1과 order2는 둘다 똑같은 곳에서 온 callOrder함수를 참조하고 있는 것을 확인할 수 있다.


- 결론

  • “this” 키워드를 사용해서 method를 만들면, 각 instance들은 각자 고유한 method copy들을 가지게 될 것이다. 이것은 가능한 피해야할 상황인데, 바로 인스턴스들이 늘어날수록 더 많은 메모리가 들기 때문이다. 또한, 만약 어떠한 이유로 개발자가 모든 인스턴스들을 수정해야 한다면, 모든 인스턴스를 일일히 수정해야 될 것이다.
    ( 그냥 prototype으로 설정해서 해당 method만 수정하면 될 것을… )
  • 그렇다고, this가 쓸모없는 것은 아니다.
    만약, 기본 method와 유사하지만 각 인스턴스마다 고유한 특징이 있어서 약간의 변화를 줘야할 때, 생성자에서 method를 this를 통해서 만드는 것이 더 좋은 방법이다.
  • 결론은, 당신이 자원과 메모리를 최적화시키고 싶다면, prototype을 써야한다. 생성자 안에서 선언하는 것은 object redundancy를 야기한다.
    특히, this를 사용해서 복사하려는 properties들이 method일 때 더더욱!!!!!!!

자료출처

오늘 TIL은 코드스테이츠에서 학습한 내용과 Udemy에서 학습한 내용들을 바탕으로 작성됐다.

profile
좋은 길로만 가는 "조은길"입니다😁
post-custom-banner

0개의 댓글