JavaScript

⭐JavaScript Closure⭐

NEWDODORIPYO 2022. 5. 7. 15:22

JavaScript Closure 정리 <감춰진 참조>

  • 어떤 함수나 객체가 다른 곳에 있는 데이터나 변수를 사용해야 하는데 개발자가 직접 명시적으로 참조하지 않아도 자동으로 참조가 되는 현상을 **Closure라고 함
  • 변숫값을 참조하는 것이 아닌 메모리 공간 를 참조하는것
  • Closure 사용하면 메모리를 많이 사용하게 된다는 단점이 있다
  • 함수를 이용해서 상태를 유지하는 객체를 만들 때 많이 사용된다

내부 함수가 유효한 상태에서 외부 함수가 종료하여 외부함수의 실행 콘텍스트가 반환되어도, 외부함수 실행 컨텍스트 내의 활성 객체(Activation object)(변수, 함수 선언 등의 정보를 가지고 있다)는 내부 함수에 의해 참조되는 한 유효하여 내부 함수가 스코프 체인을 통해 참조할 수 있는 것을 의미한다.

즉 외부 함수가 이미 반환되었어도 외부함수 내의 변수는 이를 필요로 하는 내부 함수가 하나 이상 존재하는 경우 계속 유지된다. 이때 내부함수가 외부 함수에 있는 변수의 복사본이 아니라 실제 변수에 접근한다는 것에 주의하여야 한다.

 

코드로 Closure 맛보기 

<body>
    
    <button class="btn">Button 1</button>
    <button class="btn">Button 2</button>
    <button class="btn">Button 3</button>

    <script>
        
        const arr = document.querySelectorAll(".btn")
        
        for(var i=0; i < arr.length; i++){
            
            arr[i].addEventListener("click" , function(){
               
                alert(i)
           
            }, false)

        }
    </script>


</body>

각 버튼에 클릭 이벤트를 넣어주었다 화면에서 버튼을 눌러보자

🤷‍♂️어떤 버튼을 눌러도 3이 나온다 분명 for 루프를 통해 i++를 해주었는데 왜 이런 결과가 나올까?

arr[i].addEventListener("click" , function(){
               
                alert(i)
           
            }, false)

현재 function의 범위에는 i라는 변수가 없습니다 그렇기에 사용하려면 다른 곳에서 가져다 써야 합니다 하지만 원래 함수는 한번 실행되고 나서 지역변수가 생성이 되고 실행이 끝나면 지역변수 들은 다 사라져야 하는데  지금 그러지 못하고 있다

 

for문에 var를 let으로

<body>
    
    <button class="btn">Button 1</button>
    <button class="btn">Button 2</button>
    <button class="btn">Button 3</button>

    <script>
        
        const arr = document.querySelectorAll(".btn")
        
        for(let i=0; i < arr.length; i++){
            
            arr[i].addEventListener("click" , function(){
               
                alert(i)
           
            }, false)

        }
    </script>


</body>

화면에서 변화를 확인해보면 0 , 1 , 2 순으로 나온다

그럼 var와 let의 차이는 무엇일까?

  • var로 했을 때는 함수 내에서 호이 스팅이 생긴다
  • var에 호이 스팅 문제가 있어서 let으로 사용하는 것
  • let 은 실행될 때 자기만에 공간을 잡아준다 그래서 for 루프를 돌 때 i가 0인 공간 1인 공간 2인 공간을 만들기 때문에 결과가 0 , 1 , 2 가 나온다
  • var는 for문이 돌고 난 후 i가 3이라는 그 공간을 참조하게 돼서 결과가 3만 나오게 된다

😱var의 경우

<script>
        
        var i;
        
        const arr = document.querySelectorAll(".btn")
        
        for(i=0; i < arr.length; i++){
            
            arr[i].addEventListener("click" , function(){
               
                alert(i)
           
            }, false)

        }
    </script>

var를 사용하면 이런 식으로 선언된 것과 같은 의미를 가지게 된다

우리가 문법적으로 보는 구조와 실제로 실행하는 구조가 다르다 이걸 어휘적으로 똑같이 해석하려고 하는 게 let , const이다

 

 

두두 등장 Closure

JavaScript Closure는 읽기 쓰기 다 가능하다

함수는 원래 실행하고 나면 없어지는 게 함수인데 클로저는 그 상태를 유지하는 함수를 만들 수 있다

실행을 해보면

TOTAL 1

TOTAL 2

TOTAL 3

이 나온다

 

  • fn은 TOTAL을 직접 무는 것이 아니라 outer을 통해서 물린 <참조> 형태
  • outer가 가지고 있는 inc를 fn이 사용해 버리는 거다 없어져야 할 함수가 상태를 유지하게 된다
  • 변수로 생각해봐도 TOTAL은 지역변수 개념인데 마치 전역 변수처럼 사용되고 있다
  • inc자체가 숨겨져 있는 outer을 물고 있다고 생각하자 그래서 total을 사용할 수 있게 되는 것
  • 마치 내 것인 것처럼 사용하지만 실제로는 숨어있는 것을 사용하는 것

'JavaScript' 카테고리의 다른 글

JavaScript 모듈 패턴 오해  (0) 2022.05.07
⭐⭐호이스팅⭐⭐  (0) 2022.04.27
JavaScript 배열  (0) 2022.04.27
JavaScript 이벤트  (0) 2022.04.25
JavaScript preventDefault() , target  (0) 2022.04.24