아래의 코드는 카운터를 구현하는 함수 createCounter
를 정의하고, 이 함수를 사용하여 각각의 독립적인 카운터 인스턴스를 생성하는 예제입니다. 각각의 카운터 인스턴스는 자체적인 값을 유지하며, increment
함수를 호출할 때마다 값이 증가합니다.
function createCounter() {
let count = 0;
function increment() {
count++;
console.log(count);
}
return increment;
}
const counter1 = createCounter();
const counter2 = createCounter();
counter1(); // 1
counter1(); // 2
counter2(); // 1
위의 예제에서 createCounter
함수는 내부에 count
라는 변수를 선언하고, increment
라는 함수를 정의합니다. increment
함수 내부에서는 외부에 선언된 count
변수에 접근하여 값을 변경하고 출력합니다.
createCounter
함수는 increment
함수를 반환하므로, counter1
과 counter2
는 각각 독립적인 increment
함수를 참조하게 됩니다. 이때 increment
함수는 자신이 선언된 환경인 createCounter
함수의 스코프에 대한 클로저를 형성합니다. 따라서 counter1
과 counter2
를 호출할 때마다 각자의 독립적인 count
변수에 접근하여 값을 증가시킬 수 있습니다.
이를 통해 클로저를 사용하여 각각의 카운터 인스턴스가 독립적인 상태를 유지할 수 있게 됩니다.
createCounter
함수는increment
함수를 반환하므로,counter1
과counter2
는 각각 독립적인increment
함수를 참조하게 됩니다. 왜 일까?
createCounter 함수가 호출될 때마다 새로운 렉시컬 환경과 그 안에 포함된 increment 함수가 생성되는 것입니다. 이렇게 생성된 increment 함수는 자신이 생성될 당시의 렉시컬 환경을 기억하고 있기 때문에, 독립적으로 변수를 유지하고 값을 변경할 수 있습니다.
함수가 호출될 때마다 새로운 렉시컬 환경이 생성되는 이유는 자바스크립트의 실행 컨텍스트(Execution Context)와 스코프 체인(Scope Chain) 동작 원리에 기인합니다.
각각의 함수 호출은 자체적인 실행 컨텍스트를 생성합니다. 실행 컨텍스트는 함수가 실행되는 동안 필요한 정보를 담고 있는 객체로, 변수, 함수 선언, 매개변수 등의 정보를 가지고 있습니다. 실행 컨텍스트는 함수가 호출될 때 생성되고, 함수의 실행이 완료되면 제거됩니다.
또한, 실행 컨텍스트는 스코프 체인을 형성합니다. 스코프 체인은 함수가 변수를 참조할 때 변수를 검색하는 메커니즘으로, 실행 컨텍스트의 렉시컬 환경들이 연결된 리스트 형태로 구성됩니다. 각각의 렉시컬 환경은 변수와 함수 선언을 포함하고 있으며, 외부 환경에 대한 참조를 가지고 있습니다.
createCounter
함수가 호출될 때마다 새로운 실행 컨텍스트가 생성되고, 해당 실행 컨텍스트는 새로운 렉시컬 환경을 생성합니다. 이렇게 생성된 렉시컬 환경은 이전에 호출된 createCounter
함수의 렉시컬 환경과 독립적으로 존재하며, 각각의 렉시컬 환경은 고유한 변수와 함수 선언을 가지고 있습니다.
따라서, createCounter
함수를 호출할 때마다 독립적인 렉시컬 환경이 생성되는 것입니다. 이는 각 호출이 서로 다른 변수를 유지하고 독립적으로 동작할 수 있도록 보장합니다.
렉시컬 환경(Lexical Environment)은 자바스크립트에서 변수, 함수 선언 등의 식별자(identifier)와 해당 식별자에 대한 값(Value)들이 저장되는 데이터 구조입니다. 렉시컬 환경은 실행 컨텍스트(Execution Context)의 일부로 생성되며, 실행 컨텍스트는 코드가 실행될 때 해당 코드의 환경을 추상화한 개념입니다.
렉시컬 환경은 크게 두 가지 요소로 구성됩니다:
환경 레코드(Environment Record): 변수, 함수 선언 등의 식별자와 해당 식별자에 대한 값을 저장하는 데이터 구조입니다. 환경 레코드는 식별자의 이름과 값에 대한 매핑 관계를 가지고 있습니다. 예를 들어, 변수에 대한 값이나 함수의 위치와 같은 정보를 저장합니다.
외부 렉시컬 환경 참조(Outer Lexical Environment Reference): 현재 렉시컬 환경과 연결된 외부(상위) 렉시컬 환경을 가리키는 참조입니다. 이를 통해 스코프 체인(Scope Chain)을 형성하여 변수와 함수를 검색할 때 사용됩니다. 외부 렉시컬 환경 참조는 중첩된 함수나 블록 스코프가 있는 경우, 해당 외부 스코프의 렉시컬 환경을 참조하게 됩니다.
렉시컬 환경은 코드가 실행되는 동안 식별자의 유효 범위와 값을 저장하고 검색하는데 사용됩니다. 예를 들어, 변수에 값을 할당하거나 변수를 참조하는 등의 동작은 렉시컬 환경을 통해 이루어집니다. 또한, 함수 선언도 렉시컬 환경에 저장되어 해당 함수를 참조하고 호출하는 데 사용됩니다.
렉시컬 환경은 자바스크립트 엔진에 의해 내부적으로 관리되며, 실행 컨텍스트의 일부로서 코드 실행에 필요한 식별자와 값의 매핑을 제공합니다.