html,css,js

[자바스크립트 중급] 클로저 (Closure), 어휘적 환경(Lexical Environment)

코복이 2023. 5. 9. 15:57
728x90

1. 들어가며

- 자바스크립트는 어휘적 환경을 갖는다. (Lexical Environment) = (Lexical Scope 라고도 함)
- 코드를 실행하면 해당 스크립트의 변수들이 Lexical Environment에 들어감.
- 렉시컬 환경은 크게 '전역/내부 렉시컬'로 나누며 한 스크립트에 여러가지 렉시컬 환경이 나올 수 있음.
- 내부 렉시컬 환경은 자기보다 외부/전역 렉시컬 환경을 참조할 수 있음 (내부를 찾다가 없으면 점점 외부로나감)
- 외부로 나가며 기억했던 변수들을 참조함


- 실행 예시
1)코드 실행 (한줄 씩 내려감)
2)스크립트에 변수 다 전역 렉시컬 환경에 저장
3)내려와서 add3 변수 안에 있는 makeAdder함수 만나고 x 값을 얻음 (makeAdder 렉시컬 환경에 x값 저장)
4)makeAdder(3)으로 makeAdder 함수 한번 실행되어 이제 add3도 실행 가능
4)내려와서 add3(2) 에서 y 값도 얻음 (익명함수 (걍 function())의 렉시컬 환경에 y값 저장)
5)이제 결과값인 x+y를 하는데 안에서 밖으로 나가며 값을 찾음.
 
정리하면, ‘차량용 썬팅‘이다.
안에서는 밖이 보이지만 밖에서는 안이 안보인다.

안쪽에 있는 렉시컬 환경은 자기보다 외부, 전역에 있는 렉시컬 환경을 참조/접근할 수 있다.
=> 안쪽에 있는 내부 함수가 외부에 있는 함수의 변수를 기억하고 접근할 수 있다.
 
이러한 메커니즘을 '클로저'라 함.
 
 

2. 클로저 (Closure)

- 함수와 렉시컬 환경의 조합.
- 함수가 생성될 당시의 외부 변수를 기억하여 생성 이후에도 계속 접근 가능한 것을 뜻함.
- 현재 상태를 기억하고 변경된 최신 상태를 유지
- 외부함수는 이미 실행이 끝났는데도 내부함수가 외부함수의 변수를 기억하고 참조 할 수 있음.

* 여기보면 add10 에 makeAdder(10)의 실행이 끝났는데도, add3(1)은 여전히 makeAdder(3)의 변수를 기억.
* 즉, add(10)과 add(3) 은 서로 다른 렉시컬 환경을 가지고 있다.
 
📌 예문 1 : 클로저로 최신값을 기억함

// closure 클로저 예문

function makeCounter() {
    let num = 0; // 2)외부 함수의  num 변수 값을 기억하고 있음
    return function() {
        return num++
    }; // 1)내부 함수에서
};

let counter = makeCounter();

console.log(counter()); // 0
console.log(counter()); // 1
console.log(counter()); // 2 // 외부의 num 변수값을 기억하고 실행할 때마다 1씩 올림

 
📌 예문 2 : 클로저로 현재값을 최신상태로 유지

<!DOCTYPE html>
<html>
<body>
  <p>전역 변수를 사용한 Counting</p>
  <button id="inclease">+</button>
  <p id="count">0</p>
  <script>
    var incleaseBtn = document.getElementById('inclease');
    var count = document.getElementById('count');

    // 카운트 상태를 유지하기 위한 전역 변수
    var counter = 0;

    function increase() {
      return ++counter;
    }

    incleaseBtn.onclick = function () {
      count.innerHTML = increase();
    };
  </script>
</body>
</html>

 

728x90