본문 바로가기

web../javascript

자바스크립트 코어 - 생성자와 프로토타입

자바스크립트 생성자를 정의해 보자.

예제1)

      function Rectangle(width, height){

this.width = width;

this.height = height;


this.area = function(){

rerurn this.width * this.height;

}

}


문제점이 있다. 이 방법을 통해 객체를 생성하면, 생성된 모든 사각형 객체는 프로퍼티를 세 개(width, height, area) 가진다.

객체마다 width와 height 프로퍼티의 값은 다르겠지만, 

Rectangle 객체의 area 프로퍼티는 항상 같은 함수를 의미한다. 즉, 한 클래스에 속하는 객체들이 공유하게끔 만들어진 메서드에, 일반적인 프로퍼티를 사용하는 것은 비효율적이다.

이를 해결하기 위해서는 프로토타입을 활용해야 한다.







# 프로토타입이란??

자바스크립트의 모든 객체는 프로토타입이라고 불리는 또 다른 객체를 내부적으로 참조한다. 그리고 객체는 프로토타입의 프로퍼티들을 자신의 프로퍼티로 가져온다. 즉, 결론은 자바스크립트이 객체는 자신의 프로토타입에 있는 프로퍼티들을 상속받는다는 것이다.

예제2)

      function Rectangle(width, height){

this.width = width;

this.height = height;

}

//프로토타입 객체는 각 인스턴스들이 공유해야 하는 프로퍼티나 메서드를 정의 한다.

//메서드 뿐만 아니라 상수를 정의하기에도 좋다.

      Rectangle.prototype.area = function(){ return this.width * this.height; } 


예제2 는 예제1을 프로토타입을 이용하여 메서드를 정의 한 것이다. 위에서도 언급했지만 자바스크립트 객체는 자신의 프로토타입에 있는 프로퍼티들을 상속 받기 때문에 모든 Rectangle의 객체에는 area 메서드 동작이 가능하며, 상속받은 프로퍼티는 객체의 일반적인 프로퍼티처럼 작동한다.


프로토타입을 사용하면 오는 장점으로는..

1. 메모리의 양을 상당히 줄일수 있다.

2. 프로토타입에 새로운 프로퍼티가 추가되면, 이미 생성되었던 객체일지라도 추가된 프로퍼티를 그대로 상속 받는다.







# 프로토타입의 동작 방식

-> 객체 o의 프로퍼티 p를 읽을 때 자바스크립트는 o에 p라는 이름을 가진 프로퍼티가 있는지 검사한다.

-> 만약 없다면 o의 프로토타입 객체에 p라는 프로퍼티가 있는지 검사한다.


-> 프로퍼티의 값을 쓰려고 할 때는 프로토타입 객체를 사용하지 않는다.

예제3) 
<script>

function Circle(radius){

this.radius = radius;

}

Circle.prototype.area = function(){ 

return this.radius * this.radius * this.pi 

} //메서드 정의

Circle.prototype.pi = 3.14;


var c = new Circle(3);

alert( c.area() ); // ① 28.26출력

c.pi = 1;

alert( c.area() ); // ② 9출력

delete c.pi;

alert( c.area() ); // ③ 28.26출력

</script>


예제3 에서 28.26 이라는 원의 넓이가 출력 되었다가 c.pi라는 c객체의 프로퍼티를 정의 했다. 그렇게 된다면 area() 메서드의 this.pi는 

프로토타입의 pi가 아닌 c 객체의 pi가 되므로 9가 출력된다. 이유는 위에서 언급했다. 





결론은 프로토타입의 프로퍼티들은 클래스의 모든 객체가 공유하기 때문에, 모든 객체가 같이 사용하는 프로퍼티들을 정의해놓는 것이 이해하기 쉽다. 

즉, 프로토타입은 메서드를 정의해두기 좋다.

     상수를 정의하기에 적당하다.