자바스크립트의 프로토타입은 생성자 함수의 단점인 중복 멤버 생산을 줄여주는 역할을 합니다. 프로토타입을 사용하면, 반복되는 메서드나 속성을 따로 저장을해서 메모리 사용량을 줄일 수 있습니다.
자바스크립트 생성자 함수로 만든 객체의 단점
생성자 함수가 객체 상수의 단점을 보강하는 것 처럼, 프로토타입은 생성자 함수의 단점을 보완합니다.
생성자 함수로 속성과 메서드의 틀을 만들 때 보통 메서드는 변하지 않는 경우가 많습니다. 하지만 new
키워드로 객체를 만들 때 마다 똑같은 메서드가 메모리에 계속 저장됩니다.
아래 예제를 보면 tesla
객체와 costco
객체를 만들 경우 똑같은 함수인 downdown();
메서드가 메모리에 각각 저장되므로 중복의 낭비가 발생합니다.
<script>
//생성자 함수 선언
function Stock ( name, price )
{
this.name = name;
this.price = price;
this.downdown = function ()
{
this.price *= 0.99;
};
}
//테슬라 객체 생성
var tesla = new Stock("테슬라", 305871);
tesla.downdown();
document.write(tesla.name + " 주가는 " + tesla.price + "로 1% 하락했습니다." + "<br>");
//코스트코 객체 생성
var costco = new Stock("코스트코", 268529);
costco.downdown();
document.write(costco.name + " 주가는 " + costco.price + "로 1% 하락했습니다." + "<br>");
</script>
결과
테슬라 주가는 302812.29로 1% 하락했습니다.
코스트코 주가는 265843.71로 1% 하락했습니다.
프로토타입을 사용하면, 생성자 함수에서 발생하는 중복 저장 멤버를 하나에만 저장하고, 호출하는 방식으로 메모리를 절약할 수 있습니다.
메서드의 프로토타입 생성
중복이 되어 다른 객체에도 동일한 메서드를 찾아서 생성자 함수 밖으로 뺀 다음 함수를 다시 만들면 됩니다.
이 때 함수명은 this.함수명
에서 생성자함수명.prototype.함수명
의 형태로 변경됩니다. 나머지 함수 내부의 코드 블록을 설정하는 과정은 동일합니다.
<script>
//생성자 함수 선언
function Stock ( name, price )
{
this.name = name;
this.price = price;
}
//메서드 프로토타입 선언
Stock.prototype.downdown = function ()
{
this.price *= 0.99;
};
//테슬라 객체 생성
var tesla = new Stock("테슬라", 305871);
tesla.downdown();
document.write(tesla.name + " 주가는 " + tesla.price + "로 1% 하락했습니다." + "<br>");
//코스트코 객체 생성
var costco = new Stock("코스트코", 268529);
costco.downdown();
document.write(costco.name + " 주가는 " + costco.price + "로 1% 하락했습니다." + "<br>");
</script>
결과
테슬라 주가는 302812.29로 1% 하락했습니다.
코스트코 주가는 265843.71로 1% 하락했습니다.
출력 결과는 프로토타입을 사용하지 않은 것과 동일합니다. 하지만 컴퓨터의 메모리 사용 관점에서는 낭비가 줄었습니다.
속성의 프로토타입 생성
생성자 함수에 지정된 속성(property)도 객체마다 동일한 경우가 있다면, 반복을 제거하기 위해서 프로토타입(prototype)으로 지정할 수 있습니다.
예를 들어 아래와 같이 Stock
생성자 함수에서 this.market = "S&P 500"
속성은 매개변수없이 고정된 값입니다. 따라서 객체 생성 마다 쓸데없는 반복으로 메모리 공간을 차지하게 됩니다.
<script>
function Stock ( name, price )
{
this.name = name;
this.price = price;
//반복되는 속성(property)
this.market = "S&P 500";
}
</script>
메서드처럼 속성도 프로토타입으로 외부로 빼내서 정의하면 됩니다. 마찬가지로 사람 눈에는 출력 결과가 프로토타입을 사용한 것과 사용하지 않은 것이 동일하지만 기계상으로 메모리 사용량이 줄어들게 됩니다.
<script>
//생성자 함수 선언
function Stock ( name, price )
{
this.name = name;
this.price = price;
}
//속성 프로토타입 선언
Stock.prototype.market = "S&P 500";
//객체 생성
var tesla = new Stock("테슬라", 305871);
var costco = new Stock("코스트코", 268529);
//tesla 객체 멤버 모두 출력
for ( var num in tesla )
{
document.write(num + "\t" + tesla[num] + "<br>");
}
//costco 객체 멤버 모두 출력
for ( var num in costco )
{
document.write(num + "\t" + costco[num] + "<br>");
}
</script>
결과
name 테슬라
price 305871
market S&P 500
name 코스트코
price 268529
market S&P 500
프로토타입의 개념을 잘 이해하면 내장 객체의 Object
객체나 다른 내장 객체의 메서드가 왜 같이 사용되는지 이해할 수 있습니다.