javascript/모던 자바스크립트 Deep Dive

렉시컬스코프와 클로저의 차이점

yongfront 2024. 2. 9. 12:50
반응형
SMALL

렉시컬 스코프(Lexical Scope)와 클로저(Closure)는 프로그래밍 언어에서 변수의 범위(scope)와 접근성을 결정하는 중요한 개념입니다. 두 개념은 서로 밀접하게 관련되어 있으나, 명확한 차이가 있습니다.

렉시컬 스코프(Lexical Scope)

  • 정의: 렉시컬 스코프(또는 정적 스코프)는 변수가 코드를 작성하는 시점에 결정되는 변수의 범위를 말합니다. 즉, 변수가 함수 내부에서 정의되었다면, 그 함수 내부에서만 접근할 수 있으며, 중첩된 함수의 경우 내부 함수에서는 외부 함수의 변수에 접근할 수 있지만, 외부 함수에서는 내부 함수의 변수에 접근할 수 없습니다.
  • 특징: 함수의 실행 컨텍스트가 아니라, 함수가 작성된 위치에 따라 변수의 접근성이 결정됩니다.

클로저(Closure)

  • 정의: 클로저는 함수와 그 함수가 선언될 때의 렉시컬 환경의 조합입니다. 이를 통해 함수는 선언될 당시의 환경을 '기억'하며, 이 환경 밖에서 호출되어도 그 환경에 있는 변수에 접근할 수 있습니다.
  • 특징: 클로저를 통해 외부 함수가 종료된 후에도 그 함수의 변수에 접근할 수 있는 방법을 제공합니다. 이는 프라이빗(private) 변수를 구현하거나, 고차 함수에서 매우 유용하게 사용됩니다.

차이점

  • 적용 범위: 렉시컬 스코프는 변수가 접근할 수 있는 범위를 정의하는 규칙이며, 클로저는 이러한 범위 규칙을 활용하여 특정 함수에서만 접근 가능한 변수를 '기억'하게 만드는 기능입니다.
  • 주요 목적: 렉시컬 스코프는 코드의 구조를 통해 변수의 접근성을 결정하는 것이 목적이고, 클로저는 특정 스코프에 속한 변수들을 함수가 종료된 후에도 접근 가능하게 하는 것이 목적입니다.

간단히 말해, 렉시컬 스코프는 변수가 어디에서 접근 가능한지를 결정하는 규칙이고, 클로저는 그러한 스코프의 규칙을 '이용'하여, 함수가 선언될 때의 환경을 나중에도 '기억'하게 하는 특별한 함수입니다. 클로저는 렉시컬 스코프의 개념 위에 구축되어, 프로그래밍에서 보다 강력한 기능을 가능하게 합니다.

 

렉시컬 스코프 예제

렉시컬 스코프는 변수가 코드 상에서 정의된 위치에 의해 그 범위가 결정되는 개념입니다. 예를 들어:

function outerFunction() {
  var outerVar = 'I am outside!';

  function innerFunction() {
    console.log(outerVar); // 'I am outside!' 출력
  }

  innerFunction();
}

outerFunction();

이 예제에서 **innerFunction**은 outerFunction 내에 정의되어 있으며, **outerFunction**의 변수 **outerVar**에 접근할 수 있습니다. 이는 렉시컬 스코프의 원리에 따른 것입니다. 즉, **innerFunction**의 스코프는 그것이 정의된 시점의 상위 스코프에 의해 결정됩니다.

클로저 예제

클로저는 함수가 자신이 생성될 때의 환경을 '기억'하게 해주는 기능입니다. 이를 통해 함수는 외부 함수의 실행이 끝난 후에도 외부 함수의 변수에 접근할 수 있습니다.

function createFunction() {
  var secretVar = 'Secret message';

  function accessSecretVar() {
    return secretVar;
  }

  return accessSecretVar;
}

var myClosure = createFunction(); // createFunction이 실행을 마치고 나서도,
console.log(myClosure()); // 'Secret message' 출력

이 예제에서 accessSecretVar 함수는 createFunction 함수의 secretVar 변수에 접근합니다. **createFunction**이 실행 완료되고 반환된 후에도, accessSecretVar 함수는 **secretVar**에 접근할 수 있습니다. 이는 클로저 덕분입니다.

프라이빗 변수 사용 예제

클로저를 사용하면 JavaScript에서 프라이빗 변수를 구현할 수 있습니다. 이 변수들은 함수 외부에서 직접 접근할 수 없습니다.

function counter() {
  var count = 0; // 이 'count' 변수는 counter 함수 내부에서만 접근 가능합니다.

  return {
    increment: function() {
      count++;
      return count;
    },
    decrement: function() {
      count--;
      return count;
    }
  };
}

var myCounter = counter();

console.log(myCounter.increment()); // 1
console.log(myCounter.increment()); // 2
console.log(myCounter.decrement()); // 1

이 예제에서 count 변수는 외부에서 직접 접근할 수 없는 프라이빗 변수로 동작합니다. **increment**와 decrement 함수는 count 변수를 수정할 수 있지만, 이는 클로저를 통해 가능한 것입니다. 함수 외부에서는 이 변수에 직접 접근할 수 없으므로, 데이터를 보호할 수 있습니다.

이와 같이 렉시컬 스코프와 클로저는 JavaScript 프로그래밍에서 매우 중요한 개념으로, 변수의 범위와 접근성을 제어하는 데 사용됩니다.

 

 

추가 이해 도움 예제

출처 : 코딩앙마님 클로저 5분만에 이해하기

let one;
one = 1;

function addOne(num) {
    console.log(one + num);
}

addOne(5);


함수 addOne 은 전역 렉시컬 환경의 one 1과 내부 렉시컬 환경 num : 5 두가지를 가질 수 있다.

addOne 이 실행 될 때 처음 one 을 찾지만 내부 렉시컬엔 값이 없음

전역 렉시컬 환경에서 1을 찾는다

실행 값은 6

자세한 설명은 https://www.youtube.com/watch?v=tpl2oXQkGZs

 

728x90
반응형
LIST