본문 바로가기

자바스크립트 문법 (14) private, public 프로토타입 객체모델

by Recstasy 2019. 5. 18.

(14) private, public[프로토타입] 객체모델


'프라이버시' , '공개적인' 반대편에 있는 단어다. 프라이버시라는 의미는 사적인 공간을 뜻한다. 반면, 퍼블릭은 공적이며, 대중적인 공간을 상징한다. 프로그램 개발에 있어서도 보안적을 강조할 때 프라이버시적인 방법을 구사할 수 있다. 


 퍼블릭 방식은 굳이 보안에 신경쓸 필요가 없는 간단한 속성 코드를 작성할 때 사용한다고 알아두면 되겠다. 그러나 아무나 오갈수 있는 코드를 객체지향 코드를 작성하려는 프로그래머는 그리 많지 않을 것이다. 이번 포스팅에서는 보안을 강조할 수 있는 방식과 그 반대의 코드를 알아보자.


1 private 멤버 정의하기

private 멤버란, 말 그대로 외부에서 접근할 수 없는 '개인 사생활'과 같은 변수나 메소드를 작성하는 방식이다. 프로토타입 객체모델 안에는 수많은 변수와 메소드들이 있다. 쉽게 말해, 코드 내 함수에 접근하려면 특정 조건을 갖춰야만 할 수 있도록 만드는 방식이 private방식이다. 아래 예제를 보자.



var Triangle = function( ){

var _width;

var _height;

var argsChk = function(val){

                     return (typeof val === 'number' && val >0 )

                   };

this.setWidth = function(width){

   if( argsChk(width) ){

         _width = width;

      }

  };

this.getWidth = function( ){

                       return _width;

                    };

this.setHeight = function( height ){

                           if( argsChk( height )){

                                 _height = height;

                              }

                        }

this.getHeight = function( ){

                            return _height;

                      }

 }

Triangle.prototype.getArea = function( ){

                         return this.getWidth( ) * this.getHeight( ) / 2;

                     };

var t = new Triangle( );

     t.setWidth(5);

     t.setHeight(10);

console.log(t.getWidth( ));

console.log(t.getHeight( ));

console.log(t.getArea( ));


위의 코드는 삼각형 넓이를 구하는 Triangle 프로토타입 객체이다. Triangle 프로토타입 객체 안에는 _width와 _height라는 변수가 있다. "_width와 _height"는, Triangle( )을 상속받은 t라는 객체로 접근할 수 없다.


가령,

t._width = 20;

t._height = 4;

라고 입력을 하고 난 후에, t.getArea( ) 명령을 실행하면, NaN 값이 나온다.


_width와 _height 변수에는 오로지 setWidth( )와 setHeight( ) 메소드로만 접근가능하다. 

argsChk (인수값 체크) 메소드로 필터링을 거친 width, height값을 this.setWidth( ), this.setHeight( ) 메소드가 _width, _height 변수값으로 전달한다.


getWidth( ), getHeight( ) 메소드는 의미 그대로 _width, _hieght 값을 외부로 내보내는 역할만 수행한다. Triangle.prototype.getArea( ) 메소드는 this키워드를 활용하여 Triangle 프로토타입의 getWidth( ) , getHeight( ) 값에 접근하고 있다.


위의 방식으로 코드를 짜고 실행을 하면, _width와 _height값은 외부에서 바로 접근할 수 없는 private 프로퍼티가 된다. 따라서 보안을 할 수 있으며, 마구잡이로 값을 넣는 행위들을 방지할 수 있는 수준높은 코드를 만들 수 있다.


private 변수에 접근할 수 있는 메소드를 previlege 메소드 (getWidth/getHeight/setWidth/setHeight)라 한다. privilege 멤버는 클로저인데, 여기서는 _width와 _height값을 반환하면서 _width,_height의 인스턴스 저장공간을 확보하고 있다.


위의 예제에서 'get메소드'만 남기고, 'set메소드'를 삭제하면, '읽기전용' 파일이 된다.


2 Object.defineProperty 사용

Object.defineProperty를 사용하면, get과 set (엑세서 프로퍼티) 을 좀더 쉽게 이용할 수 있다. 위의 코드를 Object.defineProperty로 변경해보자. 


[예제]

var Triangle = function( ){

var _width;

var _height;

var chkArgs = function(val){

                          return typeof(val === 'number' && val >0 );

                 };

Object.defineProperty( this, 'width' , {

                                      get : function( ){

                                                  return _width;

                                           },

                                      set : function(width){

                                              if(chkArgs){

                                                  _width = width;

                                               }

                                             }

                                        });


Object.defineProperty( this , 'height' , {

                                                   get : function( ){

                                                             return _height;

                                                          },

                                                   set : function(height){

                                                                  if(chkArgs){

                                                                         _height = height;

                                                                   }

                                                          }

                                                   });

                                        }

Triangle.prototype.getArea = function( ){

                                          return this.width * this.height / 2; 

                                      };

var t = new Triangle( );

     t.width = 100;

     t.height = 5;

     console.log(t.getArea( ));


위의 예제에서 눈여겨 봐야할 점은 3가지다.


1) Object.defineProperty(프로퍼티를 정의하는 객체, 프로퍼티명, 프로퍼티 구성정보) 메소드이다. defineProperty( ) 메소드의 첫번째 인자값으로는 get/set을 정의하는 프로토타입 객체를 입력하면 된다. 여기에서는 'this'를 입력했다. 두번째 인자값은, 프로퍼티명이 온다. 더이상 get이름, set이름처럼 작성하지 않아도 된다. 외부에서 프로퍼티에 

접근할 때 두번째 인자값으로 접근한다. (여기서는 width, height) 세번째 인자값에는  get/set 익명함수로 기능을 정의한다. 


2) 외부에서 prototype 메소드를 정의할 때는, Object.defineProperty의 두번째 인자값의 이름으로 접근한다. 해당 코드에서는 Traiangle.prototype = function( ){  return this.width * this.height / 2;  } 란 식으로 width 와 height 프로퍼티명으로 접근했다. 


3) get과 set의 이름을 따로 입력하지 않는다. Object.defineProperty의 장점은 get과 set의 이름을 입력할 필요없이 get과 set으로 기입하면 된다. 만일, 중복을 줄이면, 아래처럼 간추려 사용할 수 있다.


Object.defineProperty( this, {


width: {

get:function( ){

return _width;

},

set:function(width){

if( typeof width === 'number' && width > 0 ){

_width = width;

 

}

},

height: { this, {

height: {

get:function( ){

return _height;

},

set:function(height){

if( typeof height === 'number' && height > 0 ){

_height = height;

}

}

  }

}

})




댓글

최신글 전체

이미지
제목
글쓴이
등록일