📜 Js

[JavaScript] 프로토타입 쓰는 이유, 목적 그리고 사용법

loose 2022. 12. 18. 11:58
반응형

사용 목적

프로토타입은 자바스크립트의 최적화를 위해 사용된다.

 

사용 방식

자바스크립트는 아래와 같이 함수형으로 객체 생성이 가능하다.

function Person(first, last, age, eyecolor) {
  this.firstName = first;
  this.lastName = last;
  this.age = age;
  this.eyeColor = eyecolor;
}

const myFather = new Person("John", "Doe", 50, "blue");
const myMother = new Person("Sally", "Rally", 48, "green");

 

여기서 국적(nationality)이라는 변수를 하나 더 만들어보자.

function Person(first, last, age, eyecolor) {
  this.firstName = first;
  this.lastName = last;
  this.age = age;
  this.eyeColor = eyecolor;
  this.nationality = "English";
}

const myFather = new Person("John", "Doe", 50, "blue");
const myMother = new Person("Sally", "Rally", 48, "green");

각각의 객체는 firstName, lastName, age, eyeColor, nationality 총 5개의 변수가 할당되었으므로 총 10개의 변수가 할당이 돼서 메모리에는 10개의 변수가 올라간 상태다. 

 

하지만 nationality는 변하지 않는 값인데도 객체를 생성할 때마다 메모리가 불필요하게 많이 쌓이게 된다.

이러한 문제점을 prototype을 이용하면 공유된 메모리로 사용할 수 있게 된다.

function Person(first, last, age, eyecolor) {
  this.firstName = first;
  this.lastName = last;
  this.age = age;
  this.eyeColor = eyecolor;
}

Person.prototype.nationality = "English";  //기능이 같으므로 메모리에 1번만 올려서 사용

Person.prototype.name = function() { //기능이 같으므로 메모리에 1번만 올려서 사용
  return this.firstName + " " + this.lastName;
};

const myFather = new Person("John", "Doe", 50, "blue");
const myMother = new Person("Sally", "Rally", 48, "green");

이제 nationality 변수는 공유된 메모리로 객체를 몇번을 생성하든 메모리에 1개만 올라가게된다.

그러므로 firstName, lastName, age, eyeColor 4개의 변수가 2번할당 됐으니 8개가 올라가고 공유된 nationality 변수와 함께 총 9개가 메모리 할당이 됐다고 보면된다.

 

실제 메모리 할당 확인하기

 

개발자도구에서 Memory에서 Timeline 형식으로 메모리 할당을 관측할 수 있다.

실험해볼 코드는 아래 2가지다.

 

최적화 하지 않은 코드

function Person(first, last, age, eyecolor) {
  this.firstName = first;
  this.lastName = last;
  this.age = age;
  this.eyeColor = eyecolor;
  this.nationality = "English";
}

const myFather1 = new Person("John", "Doe", 50, "blue");
const myFather2 = new Person("John", "Doe", 50, "blue");
const myFather3 = new Person("John", "Doe", 50, "blue");
const myFather4 = new Person("John", "Doe", 50, "blue");
const myFather5 = new Person("John", "Doe", 50, "blue");
const myFather6 = new Person("John", "Doe", 50, "blue");
const myFather7 = new Person("John", "Doe", 50, "blue");
const myFather8 = new Person("John", "Doe", 50, "blue");
const myFather9 = new Person("John", "Doe", 50, "blue");
const myFather10 = new Person("John", "Doe", 50, "blue");

콘솔을 통해 위 코드를 입력할 시에 2.3kb의 메모리 할당이 생긴 것을 확인할 수 있다.

매번 같은 용량은 아니지만 평균 2.5kb가 할당되었다.

 

최적화한 코드(Prototype)

function Person() {

}
Person.prototype.firstName = "Doe"
Person.prototype.lastName = "Doe"
Person.prototype.age = 50;
Person.prototype.eyeColor = "blue"; 
Person.prototype.nationality = "English"; 

const myFather1 = new Person();
const myFather2 = new Person();
const myFather3 = new Person();
const myFather4 = new Person();
const myFather5 = new Person();
const myFather6 = new Person();
const myFather7 = new Person();
const myFather8 = new Person();
const myFather9 = new Person();
const myFather10 = new Person();

보다시피 1.7kb로 같은 개수의 객체를 생성하더라도 메모리에 할당되는 용량이 현저하게 줄어드는 것을 확인할 수 있다.

결론

 

프로토타입은 마치 자바에서 Static을 이용하는 것처럼 메모리를 공유하기 위해 사용할 수 있다.
대표적인 예시가 JQuery에 있는데 $('.someClass')를 라는 클래스 CSS 선택자를 이용해 여러개의 컴포넌트를 로드할 경우 컴포넌트 각각에 대한 메소드(.append(), remove(), html() 등 수십가지) 를 불러오게 된다고 한다.
예를 들어 .someClass로 설정된 컴포넌트가 20개고 JQuery 메소드가 20개라면 20x20을 해서 총 400번의 메모리 할당이 생기는 셈이다. 
하지만 메소드는 모든 JQuery 컴포넌트에서 공통적으로 사용하므로 메소드를 Prototype으로 만들어서 메모리의 낭비없이 사용할 수 있게되는 것이다.

728x90