[javascript]클로저 Clousure 가 뭔지 간단하게 알아보기

javascript
블로그 이미지

이챙(leechaeng)

﹒2022. 4. 5.

자바스크립트 좀 공부해봤다 하면 나오는 클로저
클로저를 처음 접하게 되면 너무 헷갈리는 개념인거 같아요.

클로저란 ? 외부함수가 반환된 후에도 내부함수가 외부함수의 변수와 파라미터에 접근할 수 있다! 라는 걸 의미합니다.

접근?? 뭐 어떻게 접근한다는건데 !!! 라는 생각을 가지고 예시를 봐봅시다.

function OuterFunction() {

    var outerVariable = 100;

    function InnerFunction() {
        console.log(outerVariable);
    }

    return InnerFunction;
}

var innerFunc = OuterFunction();

innerFunc(); // 100


변수 innerFunc에 외부함수(OuterFunction)를 호출하면 리턴 값 InnerFunction을 반환합니다. 그 상태에서 변수 innerFunc를 호출하면 내부함수(InnerFunction)가 호출되서 콘솔값이 찍히겠죠. 그럼 변수 innerFunc는 외부함수를 호출시키긴 했지만 외부함수가 아니라 내부함수(InnerFunction)만 참조합니다. 당연한거죠? 외부함수의 반환값이 내부함수니까요. 그러니까 저 변수는 난 이제 내부함수만 바라보겠다 이거에요. 근데 신기하게도 outerVariable은 외부함수에 선언한 변수인데 내부함수가 접근을 해요. 내부함수가 외부함수의 변수에 접근해서 참조할 수 있다!! 이것이 클로저입니다.

좀더 안에서 일어나는 현상을 살펴보자면, innerFunc를 호출시 외부함수가 호출이 되면 외부함수의 실행컨텍스트가 생기고 컨텍스트에 outerVariable 변수가 선언되면서 변수에 100이 담깁니다. 그리고 외부함수는 지 할일 다 끝났으니 실행컨텍스트가 소멸되요. 그리고 반환된 내부함수 실행컨텍스트가 생기면서 outerVariable 변수를 찾습니다. 그런데 내부함수에는 outerVariable 변수가 없으니 외부함수가 남기고간 outerVariable 변수를 참조해요. 그래서 결론적으로 콘솔에 100이 찍히게 됩니다. 이미 죽어버린 외부함수의 변수를 내부함수가 계속 참조하는 상황인거죠. 그래서 이때 아 클로저때문에 계속 참조가 일어나는거구나 라고 보시면 됩니다.

function OuterFunction() {

    var outerVariable = 0;

    function InnerFunction() {
        outerVariable += 1
        console.log(outerVariable)
    }

    return InnerFunction;
}

var innerFunc = OuterFunction();

innerFunc(); // 1
innerFunc(); // 2
innerFunc(); // 3

 

이번엔 내부함수를 불러올때 마다 변수에 1씩 증가하도록 해주었습니다. innerFunc함수를 계속 호출시킬때 마다 변수의 값이 증가되죠? 외부함수는 이미 죽었지만 내부함수가 계속 외부함수가 선언한 변수를 참조하면서 값이 증가되는 거에요. 내부함수에서 값이 바뀌면서 외부함수도 같이 값이 바뀌는거죠. 바로 클로저의 힘..!!! 

 



🤔그럼 왜 굳이 내부함수 외부함수 중첩해가지고 클로저를 쓰는 걸까요? 

프라이빗 함수 및 변수를 만들거나 최신상태를 유지하기위해 사용합니다.

간단하게 자주 사용하는 클릭이벤트를 사용할때 예시를 봐볼게요

<body>
    
<button id="btn">클릭</button>
<div id="text"></div>

</body>

<script>

    const $btn = document.querySelector('#btn')
    const $textbox = document.querySelector('#text')
    
    var num = 0
    function clickBtn(){
   
            num += 1
            
        $textbox.textContent = num
    }

    $btn.addEventListener('click', clickBtn)

</script>


버튼을 클릭했을때 num 변수를 증가하도록 clickBtn 함수를 호출해주었어요. 클릭하면 계속 변수의 값은 1씩 증가하겠죠. 하지만 전역변수는 프라이빗하지 않아요. 언제나 다른 변수에 의해서 참조될 가능성이 높습니다. 그러면 num변수를 clickBtn 함수안에 지역변수로 사용하면 되지 않을까 .. 라는 생각을 하게되는데 그렇게 되면 변수가 계속 0으로 선언되서 값이 바뀌지가 않겠죠. 최신유지가 되지 않아요



<body>
    
<button id="btn">클릭</button>
<div id="text"></div>

</body>

<script>

    const $btn = document.querySelector('#btn')
    const $textbox = document.querySelector('#text')

    function clickBtn(){
        var num = 0
       // console.log(1)

        function addfunc(){
            num += 1
            $textbox.textContent = num
        }

        return addfunc
    }
    var innerFunc = clickBtn()
    $btn.addEventListener('click', innerFunc)
 

</script>
</html>


위의 예시에서 배운 클로저로 클릭 이벤트를 만들어주었어요. 이렇게 되면 변수값도 최신유지가 될뿐더러 전역변수를 사용하지 않기때문에 은닉화까지 되겠죠


이챙(leechaeng)
이챙(leechaeng)

프론트엔드 개발도 하고 뛰기도 하고

'javascript' 카테고리의 관련 글