본문 바로가기

IT/JavaScript

JavaScript #3 함수-3

10. Closure
  - 내부 함수에서 자신을 포함하고 있는 외부 함수의 매개변수와 변수들을 접근할 수 있다.
    : 단, this와 arguments는 예외
  - 이 기능을 이용하면 아래와 같이 private 속성을 구현할 수 있다.
[code javascript]
var print = function (strLog) {
    document.write (strLog);
    document.write ('<br>');
};

// myObject는 함수의 실행 결과를 리턴받았기 때문에
// 외부에서 함수의 내부 변수 (var value)에 접근할 수 없다.
// 따라서 함수 내부에서 정의된 개체를 통해서만 접근할 수 있다.
var myObject = function () {
    var value = 0;

    return {
        increment: function (inc) {
            value += typeof inc === 'number' ? inc : 1;
        },
        getValue: function () {
            return value;
        }
    };
} (); // 함수의 실행한 결과를 myObject에 할당한다.

print (myObject.value); // undefined
print (myObject.getValue ()); // 0
[/code]
  - 내부 함수가 외부 함수에 있는 변수의 복사본이 아니라 실제 변수에 접근한다.
[code javascript]
<html>
<header>
<script language='javascript'>
    var add_the_handlers = function (nodes) {
        var i;
        // 원하는 기능은 각 노드에 유일한 키값을 할당하는 것이고
        // onClick이벤트가 발생하면 키값을 출력하도록 하는 것이다.
        // 하지만, Closure 기능에 의해
        // alert (i)가 호출되면 외부 함수의 var i값을 사용하게 된다.
        // 외부 함수의 var i 는 이미 4로 바뀌어 있으므로
        // onClick 이벤트가 발생하면 모두 4를 출력한다.
        // 따라서 다음 코드블럭 처럼 수정해야한다.
        for (i=0; i<nodes.length; i+=1) {
            nodes[i].onclick = function (e) {
                    alert (i);
            };
        }
    };
</script>
</header>
<body onLoad='javascript:add_the_handlers (document.frmText);'>
    <form name='frmText'>
    <input type='textbox' name='txt1' value='0'><br>
    <input type='textbox' name='txt2' value='1'><br>
    <input type='textbox' name='txt3' value='2'><br>
    <input type='textbox' name='txt4' value='3'><br>
    </form>
</body>
</html>
[/code]
[code javascript]
var add_the_handlers = function (nodes) {
    var i;
    // 편의상 i를 iIndex로 사용했다.
    // 넘겨받은 iIndex 값을 사용하기 때문에 의도한대로 정상출력된다.
    for (i=0; i<nodes.length; i+=1) {
        nodes[i].onclick = function (iIndex) {
            return function (e) {
                alert (iIndex);
            };
        } (i);
    }
};
[/code]
  - 이벤트 함수 출력을 해보려고 print (document.frmText[2].onClick);을
    호출해보았으나 undefined 로 출력되었다. 이유는 모르겠다.
    그래서 한김에 아래와 같이 수행해 보았다. 별의미는 없지만 ~ ^^;
[code javascript]
var arrFunc = [];
var testFunc = function () {
    var iIndex;
    for (iIndex = 0; iIndex < 2; iIndex ++) {
        arrFunc[iIndex] = function (iIndex) {
            return function () {
                return (iIndex);
            }
        } (iIndex);
    }
};
testFunc ();
var iIndex;
for (iIndex = 0; iIndex < arrFunc.length; iIndex ++) {
    print (arrFunc[iIndex]); // 배열에 저장된 함수 및 값을 출력한다.
    print ('arrFunc[' + iIndex + ']=' + arrFunc[iIndex]());
}
/* 실행 결과
function () { return iIndex; }
arrFunc[0]=0
function () { return iIndex; }
arrFunc[1]=1
*/
[/code]

공부한 책 : 자바스크립트 핵심가이드 - 더글라스 크락포드