클로저 자바스크립트(Closure javascript) 그리고 캡슐화 - 내부함수와 외부함수 이해
자바스크립트 클로저란(javascript Closure)?
지난 포스트에서 함수선언과 함수표현식 그리고 익명함수에 대해 정리하였습니다.
함수선언과 함수표현식 그리고 익명함수에 대해
잘모르시는 분들은 아래 링크를 클릭하세요
클로저는 간단하게 생각하면 내부함수가 외부함수의 값을 변경 할 수 있는 것을 말합니다.
이렇게만 정리하면 이해가 가지 않으므로 코드를 통해서 설명하겠습니다.
일단 아래는 클로저를 이해할 수 있는 코드로 만들어진
간단한 프로그램입니다.
위에는 텍스트 박스와 버튼이 있습니다.
숫자를 넣으신 후 실행버튼을 클릭하세요.
위의 프로그램은 html코드와 script를
밑에 공유하겠습니다.
<input type="text" id="test" />
<input type="button" id="start" value="실행" />
위에는 html코드입니다.
var text = document.getElementById("text"); var start = document.getElementById("start"); function outerFunc(obj){ return function(_obj){ // alert(typeof(_obj)); if(typeof(_obj) === "number"){ //NaN도 typeof는 number이므로 따로 처리해야한다. return obj += _obj; }else{ alert("숫자만 가능합니다."); return obj; } }; } var innerFunc = outerFunc(1); start.onclick = function(){ //alert("클릭했습니다.") var num = Number(text.value); if(!isNaN(num)){ text.value = innerFunc(num); } }
위에는 스크립트 코드입니다.
스크립트 코드 설명
var text = document.getElementById("text"); var start = document.getElementById("start");
document.getElementById를 통해서
input text와 input button을 객체로 받아와
각각 text와 start에 참조했습니다.
function outerFunc(obj){ return function(_obj){ // alert(typeof(_obj)); if(typeof(_obj) === "number"){ //NaN도 typeof는 number이므로 따로 처리해야한다. return obj += _obj; }else{ alert("숫자만 가능합니다."); return obj; } }; }
위의 코드는 함수선언을 통해 outerFunc를 정의했습니다.
그리고 return을 익명함수를 리턴하였고
익명함수의 인자가 타입이 number라면
내부함수의 지역변수 _obj와
외부함수의 obj에 +=연산자를 통하여
obj에 대입하고 있습니다.
var innerFunc = outerFunc(1);
함수선언한 outerfunc의 return한 익명함수를
innerFunc에 참조하였습니다.
start.onclick = function(){ var num = Number(text.value); if(!isNaN(num)){ text.value = innerFunc(num); } }
버튼 객체를 받아온 start에 onclick 리스너에
익명함수를 넣은 후
input 태그의 value를 가져와
숫자타입이라면
innerFunc함수에 인자값으로 넘기고 있습니다.
위의 코드를 통해 클로저에 대한 이해
다시 위로 올라가면
숫자 1을 입력하신 후 실행버튼을 클릭하시면 2가 출력되고
다시 실행버튼을 클릭하면 4,
다시 실행버튼을 클릭하면 8,
다시 실행버튼을 클릭하면 16,
그리고 실행버튼을 누르기 전 16의 값을 1로 바꾼 후
실행버튼을 클릭하면 17이 출력되는 것을 알 수 있습니다.
위의 예재로 보았을때 이상한 점을 발견 하실 수 있을 것 같습니다.
도대체 4에서 클릭하면 8이
8에서 실행버튼을 클릭하면 16이라는 값이
어떻게 나오는 걸까요?
버튼을 클릭하면 innerFunc이라는 함수를 실행합니다.
innerFunc에는 타입이 number라면
obj와 _obj를 더한 후 리턴합니다.
그렇다면 innerFunc에 있는 익명함수는
obj라는 값을 어디에 저장하고 있을까요?
클로저는 익명함수로 참조한 내부함수(innerFunc)가
참조하지 않은 외부함수(outerFunc)를 Control할 수 있는 것을 말합니다.
단순한 이론으로 지역변수는 메서드가 종료하면 값이 사라집니다.
그런데 외부함수인 outerFunc의 지역변수 obj를
innerFunc에서 가져와 자신의 지역변수인 _obj와 값을 증가 한 후
리턴한다는 것은
외부함수의 obj가 전역변수로 관리가 된다는 것을 알 수 있습니다.
이렇게 이루어진 함수를 클로저라고 부릅니다.
클로저를 통한 자바스크립트 캡슐화
위의 설명을 통해 outerFunc의 지역변수는
익명함수를 참조한 innerFunc가 변경 할 수 있다는 것을 알게되었습니다.
그렇다면 자바스크립트는 따로
자바처럼 접근제한자가 없는데 어떻게 은닉화를 할 수 있는 것일까요?
위의 설명을 이해하신 분들은 캡슐화에 대한 내용도 쉽게 이해 할 수 있을 것입니다.
outerFunc의 리턴은 익명함수를 리턴하고
outerFunc의 obj는 처음 정의할 때만
값을 초기화할 수 있습니다.
그렇다면 outerFunc의 지역변수인 obj는 처음 정의할때만 값을 초기화 할 수 있고
innerFunc를 통해서만 obj를 변경 할 수 있습니다.
그렇다면 자바에서 흔히 쓰이는 캡슐화와 동일하게
전역변수는 private로 설정하고
setter, getter메서드를 public으로 선언해 전연변수를 관리하는 것처럼
innserFunc에 setter, getter와 같은 함수를 만든다면
자바의 같이 전역변수 obj를 캡슐화 할 수 있습니다.
마치며
지금까지 자바스크립트 클로저와 클로저를 통한 캡슐화에 대한 설명이었습니다.
감사합니다.
'공감' 및 '좋아요'는 글쓴이에게 큰 힘이 됩니다!
'IT > javaScript' 카테고리의 다른 글
JavaScript Async Await Promise 사용법의 이해 (0) | 2023.01.24 |
---|---|
JavaScript 비동기 Promise에 대한 설명 (0) | 2023.01.24 |
자바스크립트 window 객체의 속성을 알아보자(자신의 브라우저에 따라 다름) (0) | 2018.06.12 |
자바스크립트 JSON 객체의 parse 및 stringify 정리. (0) | 2018.06.12 |
자바스크립트 함수선언, 함수표현식의 차이 그리고 익명함수 관련 정리 (0) | 2018.06.05 |