자바스크립트 클로저 (Closures)

자바스크립트에서 클로저는 매우 강력하고 유용한 개념입니다. 클로저를 이해하고 활용하면 코드를 더 간결하고 효율적으로 작성할 수 있습니다.

클로저란 무엇인가요?

클로저란, 함수가 자신을 둘러싼 스코프에 접근할 수 있는 것을 의미합니다. 즉, 함수가 생성된 시점의 스코프에 대한 참조를 유지하고 있는 것입니다. 이를 통해 함수 내부에서 외부 스코프의 변수에 접근할 수 있고, 해당 변수를 계속 사용할 수 있게 됩니다.

클로저의 예시

function outerFunction() {
  let outerVariable = 'I am outside!';

  function innerFunction() {
    console.log(outerVariable); // outerVariable에 접근 가능
  }

  return innerFunction;
}

let closureExample = outerFunction();
closureExample(); // "I am outside!" 출력

위 예시에서 outerFunction은 내부에 innerFunction을 정의하고 반환합니다. closureExample 변수에 outerFunction()을 호출한 결과를 할당한 후, closureExample()를 호출하면서 클로저가 동작합니다.

innerFunction 안에서 outerVariable에 접근할 수 있는 이유는 클로저 덕분입니다. innerFunction은 지역 변수인 outerVariable을 사용하기 위해 자신을 둘러싼 outerFunction의 스코프에 접근합니다.

클로저의 활용 예시

클로저를 활용하면 다양한 상황에서 유용하게 사용할 수 있습니다.

개인 정보 보호

function createPerson(name) {
  let privateName = name;

  return {
    getName: function() {
      return privateName;
    },
    setName: function(newName) {
      privateName = newName;
    }
  };
}

let person = createPerson('John');
console.log(person.getName()); // "John" 출력
person.setName('Jane');
console.log(person.getName()); // "Jane" 출력

위 예시에서 createPerson 함수는 privateName을 가진 객체를 반환합니다. 외부에서는 privateName에 직접 접근할 수 없지만, 반환된 객체의 getName 메서드와 setName 메서드를 통해 값을 읽거나 변경할 수 있습니다. 이를 통해 개인 정보를 보호하고 접근을 제한할 수 있습니다.

반복문과 비동기 작업 관리

function createButtonEvents() {
  let buttons = document.querySelectorAll('button');

  for (let i = 0; i < buttons.length; i++) {
    let button = buttons[i];

    button.addEventListener('click', function() {
      console.log('Button ' + i + ' clicked'); // 버튼의 인덱스 출력
    });
  }
}

createButtonEvents();

위 예시에서 createButtonEvents 함수는 DOM에서 가져온 여러 개의 버튼에 대한 이벤트 리스너를 등록합니다. 클릭 이벤트가 발생할 때마다 console.log를 통해 각 버튼의 인덱스를 출력합니다. 이때, 클로저가 없다면 모든 버튼을 클릭해도 항상 마지막 버튼의 인덱스만 출력될 것입니다. 하지만 클로저를 사용하면 각 버튼에 대한 클릭 이벤트 리스너가 해당 버튼의 인덱스를 기억하고 있으므로 올바른 결과가 출력됩니다.

요약

자바스크립트 클로저는 함수가 자신을 둘러싼 스코프에 접근할 수 있도록 해주는 개념입니다. 이를 활용하면 변수를 보호하고 비동기 작업을 효율적으로 처리할 수 있습니다. 클로저를 잘 이해하고 사용하면 더욱 효율적인 코드를 작성할 수 있습니다.