강좌 & 팁
글 수 2,412
2014.06.30 19:09:49 (*.134.169.166)
52023
여러분이 프로그램을 작성할 때
값을 직접적으로 참조하기 보다는 가급적 함수를 통해서 접근해라..
라는 프로그래머들의 훈수를 알고 계시나요?
분명 처리 속도가 늦져짐에도 불구하고 이런 훈수를 두는 이유는 무얼까요?
원인은 한가지 입니다.
프로그램 유지 보수를 편하게 하기 위한 것이죠..
우리에게 프로그램 작성을 부탁 하는 사람들은
그 변덕이 하늘을 찌릅니다.
결국 처음 작성된 프로그램이 똑같은 모습으로 수정 없이
만수무강 하는 경우는 본적이 없습니다.
그런데 이 분들은 프로그램 수정하는게 쉬운 줄 알아요..
하지만 여러분은 알고 있죠...
단순히 한줄을 수정하는 것이 아니고
그 한줄에 영향 받는 것들에 대한 전체 점검이 필요하기 때문에
정말 우리는 프로그램을 수정하기 싫어 한다는 사실...
어찌되었든 우리에게는 힘이 없고
프로그램은 수정해야 할 운명을 타고 났고..
그래서 수정된 프로그램의 영향이 전체 소스에 퍼지지 않도록
우리는 온갖 묘수를 동원합니다.
그 중 하나가 쎗터 겟터 라는 형태죠...
영어로 보면 setter getter 이렇게 되려나?
어찌되었던 이전의 자바스크립트는 이런거 하기 좀 어려웠습니다.
그냥 함수를 만들어 사용했지요...
뭔 말이냐고요?
실제 소스의 예를 보여 드리죠..
var 객체 = {};
객체.반지름 = 3;
console.log( 객체.반지름 );
이렇게 사용하는 것이 값을 직접 사용하는 것이죠...
이런식의 프로그램을 작성하는 경우
나중에 반지름에 값을 넣을 때 일괄적으로 + 1을 해 주는 사태가 발생하고
해당 값을 수십만줄에서 사용하고 있다면 ...
죽음이죠...
그냥 퇴사 하는 것이 마음 편할지도... 쩝...
그래서 나중에 수정할지도 모른다는 공포감으로 이렇게 합니다.
// 생성 및 선언 할 때
var 객체 = {};
객체.반지름 = 0;
객체.반지름_설정 = function( 값 ) { this.반지름 = 값; };
객체.반지름_얻기 = function() { return this.반지름 };
// 사용할 때
객체.반지름_설정( 5 );
console.log( 객체.반지름_얻기() );
이런식으로 하면 나중에 반지름에 대한 것을 일괄적으로 1 을 더 한다고 하더라도
우리는 바꿀곳은 저 둘 중 하나의 함수만 수정할수 있고
또 조건에 따라서 기존처럼 동작하게 하거나 할 수 있죠..
즉 수정에 대한 자유도가 높아 집니다.
그런데 위 처럼 하면 불편하겠죠? 매번 함수 선언해야 하는 것보다 이름이 그렇잖아요?
만약
객체.반지름 = 5;
이런식으로 한것이 실제로는
객체.반지름_설정(5);
와 동일한 효과가 발생하고..
var 결과 = 객체.반지름;
이런식으로 한것이 실제로는
var 결과 = 객체.반지름_얻기();
이것과 동일하다고 하면 좋겠죠?
이게 바로 셋터 겟터 함수라고 합니다.
아..
다행스럽게도 HTML5 에서 사용하는 자바스크립트
(보통 ECMAScript 5 라고 불리죠) 에서는
이 부분을 해결했습니다.
그래서 오늘은 이 부분을 강의 하려 합니다.
자 핵심 함수는 이겁니다.
Object.defineProperty();
여러분은 어떤 객체에 속성(property) 를 지정하려면 기존에는 이렇게 했습니다.
var 객체 = {};
객체.속성 = 3;
console.log( 객체.속성 );
그런데 이렇게 해도 됩니다.
var 객체 = {};
Object.defineProperty( 객체, '속성', { value : 3 } );
console.log( 객체.속성 );
헉...
더 복잡하죠?
Object.defineProperty() 함수는
첫번째 매개변수 인자에 속성을 정의할 대상인 객체를 지정하고
두번째 매개변수 인자에 속성의 이름을 지정하고
세번째 매개변수 인자에 속성에 대한 옵션을 지정합니다.
조금 정리하면 이렇게 두 함수가 있고 정리 될수 있습니다.
Object.defineProperty (객체명, 속성명, {옵션} ) : 객체에 속성을 하나 추가
Object.defineProperties(객체명, { 속성명: {옵션} } ) : 객체에 속성을 여러 개 추가
어찌되었던 제가 이 강좌에서 이 함수를 다루는 이유는 바로 셋터와 겟터 때문입니다.
그래도 이 함수에 대해서 조금 더 정리하고 가죠..
제일 중요한 것이 세번째 옵션 인자입니다.
옵션 인자로 줄 수 있는 것은 다음과 같습니다.
value : 속성 값
writable : 속성 값을 변경할 수 있는지의 여부(true/false)
configurable : 속성의 옵션값을 변경할 수 있는지의 여부(true/false)
enumerable : fon in 반복문으로 검사할 수 있는지의 여부(true/false)
get : 겟터 함수. value, writable 옵션과 함께 사용할 수 없습니다.
set : 셋터 함수. value, writable 옵션과 함께 사용할 수 없습니다.
위의 모든 옵션의 기본 값은 false 또는 undefined 입니다.
하나씩 살펴 보죠...
먼저 우리의 관심사 겟터와 셋터
보통 이런 것들은 자바스크립트의 클래스를 정의 할 때 많이 사용합니다.
하지만 여기서는 편의상 그냥 일반적인 샘플로 사용해 보죠..
이렇게 말이죠...
[C012_getter_setter.html]------------------------------------------------------
<!DOCTYPE html>
<html lang="ko">
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<head></head>
<body>
</body>
<script type="text/javascript">
var 원 = {};
원._반지름 = 0; // 겟터 셋터 대상 및 초기값 지정
Object.defineProperty( 원, '반지름', {
get : function() { return this._반지름; },
set : function(값) { this._반지름 = 값; }
});
// 사용예
원.반지름 = 5;
document.write('원.반지름 = ', 원.반지름);
</script>
</html>
--------------------------------------------------------------------------------
뭐 어렵지 않죠?
자 이번엔 속성을 읽기 전용으로 만들어 봅시다.
이 경우에는 두가지 샘플을 볼겁니다.
첫번째는 value 와 writale 를 사용하는 경우
이 경우에는 겟터와 셋터 를 사용하지 못하곘죠?
[C013_value_readonly]------------------------------------------------------
<!DOCTYPE html>
<html lang="ko">
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<head></head>
<body>
</body>
<script type="text/javascript">
var 원 = {};
Object.defineProperty( 원, '반지름', { value : 1 , writable : false } );
원.반지름 = 5;
document.write('<pre>');
document.write('원.반지름 = ', 원.반지름);
document.write('</pre>');
</script>
</html>
--------------------------------------------------------------------------------
이때 결과는 브라우저에
원.반지름 = 1
이 나옵니다.
두번째는 get 만 사용하는 방법입니다.
[C014_getter_setter_readonly]------------------------------------------------------
<!DOCTYPE html>
<html lang="ko">
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<head></head>
<body>
</body>
<script type="text/javascript">
var 원 = {};
원._반지름 = 1; // 겟터 셋터 대상 및 초기값 지정
Object.defineProperty( 원, '반지름', {
get : function() { return this._반지름; },
});
원.반지름 = 5;
document.write('<pre>');
document.write('원.반지름 = ', 원.반지름);
document.write('</pre>');
</script>
</html>
--------------------------------------------------------------------------------
마지막으로
enumerable 에 대해서 알아 보죠..
뭐 별거 없습니다.
프로퍼티 나열의 대상이 되는가를 지정할 수 있다는 겁니다.
외부에 프로퍼티로 보여 주고 싶지 않고 내부적으로만 사용할때 사용 가능합니다.
물론 클래스를 구성할 때 주로 쓰입니다.
다음은 시험 코드 입니다.
[C015_enumerable]---------------------------------------------------------------
<!DOCTYPE html>
<html lang="ko">
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<head></head>
<body>
</body>
<script type="text/javascript">
var 원 = {};
원.색깔 = '빨강';
Object.defineProperty( 원, '반지름', { value : 5 , enumerable : true } );
Object.defineProperty( 원, '제어값', { value : 1 , enumerable : false } );
document.write('<pre>');
document.writeln('원.반지름 = ' + 원.반지름 );
document.writeln('' );
for ( 보이는_속성 in 원 ){
document.writeln('보이는_속성 = ' + 보이는_속성 );
}
document.write('</pre>');
</script>
</html>
--------------------------------------------------------------------------------