ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [결국은 자바스크립트] 2. 클로저와 스코프 Closure & Scope
    front-end/Javascript&Typescript 2023. 6. 25. 23:09

    클로저는 함수와 해당 함수가 접근할 수 있는 자신이 생성됐을 때의 환경(lexical environment)을 함께 기억하는 개념입니다.

    클로저를 통해 함수 외부에서 내부 변수에 접근하거나 변경할 수 있습니다.

     

    클로저 첫번째 예시

        const globalVar = '전역변수입니다.';
        function outerFn(){
          const outerVar = '아우터 변수 입니다.';
          function innerFn(){
            const innerVar ='이너 변수 입니다.';
            console.log(outerVar);
            console.log(innerVar);
            console.log(globalVar);
            console.log(checkGlobalVar);
          }
          return innerFn;
        }
    
        const checkConsole = outerFn();
    
        checkConsole();

     

    위의 예시에선 전역변수로 globalVar 이 있고 , 그 밑으로 outerFn의 outerVar변수 , 또 그밑으로 innerFn의 innerVar변수가 선언 되어있고 innerFn을 리턴 합니다.

     

    그리고 콘솔에 순서대로 선언해놨던 변수를 찍고 마지막에 "checkGlobalVar" 이라는 선언 하지않은 변수도 콘솔에 찍어봅니다.

     

    콘솔의 결과가 어떻게 나올까요?

     

    콘솔의 결과를 풀어보자면 

    innerFn 클로저를 형성하고 outerVar 접근할 있기 때문입니다. 클로저는 자신이 생성됐을 때의 환경을 기억하므로, innerFn 외부 함수인 outerFn 변수에 접근할 있게 됩니다.

     

    스코프 체인은 변수의 유효 범위를 찾을 사용되는 메커니즘입니다. JavaScript에서 변수를 찾을 현재 스코프부터 상위 스코프로 거슬러 올라가며 변수를 검색합니다. globalVar 은 innerFn , outerFn의 변수의 값을 찾아보고 , 상위 함수들엔 값이 없어서 제일 상단에 선언 된 전역변수까지 찾아 올라가서 콘솔에 찍히는 겁니다.

     

    스코프 체인은 변수의 유효 범위를 찾을 현재 스코프와 상위 스코프를 거슬러 올라가며 변수를 검색하는 메커니즘을 제공합니다.

    checKGlobalVar 은 전역변수에도 선언이 안되어있어서 ReferenceError 가 납니다.

     

     

    클로저의 다른 예시도 보여드리겠습니다.

     

    클로저 두번째 예시

        function outerFn(){
          let value = 1;
          function plusValue(){
            return value ++;
          }
          function printValue(){
            console.log(value);
          }
          return {
            plusValue,printValue
          }
        }
        const add = outerFn();
    
        add.plusValue();
        add.plusValue();
        add.plusValue();
        add.plusValue();
        add.printValue();

    outerFn 안에 value란 값을 1로 초기화 시키고 plusValue() 함수로 value를 증가 시키고 , printValue로 value 값을 콘솔에 찍는

    간단한 함수입니다.

     

    outerFn 함수는 클로저를 형성하고 있습니다.

    value 변수는 outerFn 함수 내부에서 선언되어 있으므로, outerFn 내에서만 사용할 수 있습니다. 이는 value 변수가 plusValue 함수와 printValue 함수에서 접근 가능하다는 것을 의미합니다.

     

    따라서 add 변수로 통해 plusValue 함수를 여러 호출하면 value 변수가 증가하고, printValue 함수를 호출하면 현재 value 변수의 값을 출력합니다. 이를 통해 value 변수는 outerFn 함수의 내부에서만 유지되며 다른 전역 변수와 중복되지 않습니다.

     

    만약에 클로저를 통하지않고 value란 값을 전역변수에 선언하고 어디서나 value의 값에 접근할 수 있으면 어떻게 할까요?

        let value = 1;
    
        function addValue(){
          return value++;
        }
        function printValue(){
          console.log(value);
        }
    
        addValue();
        value = 0;
        addValue();
    
        printValue();

     

    예를 들어 value 란 값을 코드가 엄청 길어졌을때 선언 해놨던걸 까먹고 있다가 addValue()로 value의 값에 접근을 잘하고있다가 

    실수로 value의 변수에 0을 대입 해버리면 , 처음에 2가 출력 되다가 , 0으로 초기화 된 후 다시 1 더해져서 콘솔에 1이 찍혀있을겁니다.

    지금 말하는 예시의 상황은 절대 저희가 예상했던게 아니죠?

     

    value 변수가 전역 변수로 선언되어 있으므로, addValue 함수와 printValue 함수에서 모두 접근할 있습니다. 이는 클로저가 아니기 때문에 외부 함수의 변수에 대한 보호나 제한된 접근이 없습니다.

     

    클로저를 사용하는 경우에는 외부 함수 내의 변수가 보호되고, 외부 함수와 독립적으로 상태를 유지할 수 있으므로 이러한 충돌이 발생하지 않습니다. 클로저를 사용하면 변수를 보호하고 예기치 않은 변동을 방지할 수 있습니다.

     

     

    마무리 하면서 클로저와 스코프를 요약하자면,

     

    클로저 

    함수가 선언될 때의 렉시컬 환경(스코프)에 대한 참조를 유지하여 함수가 외부 변수에 접근할 수 있도록 하는 메커니즘.

    스코프 체인

    변수를 찾을 때 현재 스코프에서 찾지 못하면 상위 스코프로 올라가며 변수를 검색하는 메커니즘.

     

     

    간단 요약

    1.클로저는 함수가 선언될 때의 스코프를 기억하여 외부 변수에 접근할 수 있게 합니다

    2.스코프 체인은 변수를 찾을 때 현재 스코프에서 시작하여 상위 스코프로 올라가며 변수를 검색합니다.

     

Designed by Tistory.