(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;
}
}
}
}
}
})
'코드 스터디' 카테고리의 다른 글
자바스크립트 문법 (16) 반복자 & 발생자 (0) | 2019.05.20 |
---|---|
자바스크립트 문법 (15) Class (0) | 2019.05.19 |
자바스크립트 문법 (13) 객체의 타입 판정하기 (0) | 2019.05.17 |
자바스크립트 문법 (12) 객체의 상속(프로토타입 체인) (0) | 2019.05.16 |
자바스크립트 문법 (11) 프로토타입 객체 (0) | 2019.05.15 |
댓글