JavaScript/함수

[JavaScript]클로저(Closure) 개념

DevStory 2022. 6. 22.

이번 포스팅은 JavaScript의 클로저(Closure)에 대해 소개하며, 클로저를 소개하기 전에 중첩 함수와 함수 반환을 소개합니다.


중첩 함수

JavaScript에서 함수 안에 또 다른 함수를 정의하는 것을 중첩 함수라고 합니다.

 

다음 예제는 receiveName() 함수 내부에 showName() 함수를 정의합니다.

// receiveName()은 외부 함수입니다.
function receiveName(name) {
  // showName()은 reciveName() 내부에 정의되었으므로 내부 함수입니다.
  function showName() {
    console.log('name: ' + name);
  }
  showName();
}

receiveName('홍길동');

실행 결과

name: 홍길동

showName() 함수는 receiveName() 함수 내부에서만 호출할 수 있습니다.


함수 반환

JavaScript에서 함수 안에서 다른 함수를 반환할 수 있습니다.

 

다음 예제는 receiveName() 함수 내부에 정의된 showName() 함수를 반환합니다.

// receiveName()은 외부 함수입니다.
function receiveName(name) {
  // showName()은 reciveName() 내부에 정의되었으므로 내부 함수입니다.
  function showName() {
    console.log('name: ' + name);
  }
  return showName;
}

const func = receiveName('홍길동');
console.log(func);
func();

실행 결과

ƒ showName() {
    console.log('name: ' + name);
  }
name: 홍길동

receiveName() 함수가 showName() 함수를 반환하므로 func를 console에 출력해보면, 함수의 정의문을 확인할 수 있습니다. func는 함수를 반환받았으므로 함수처럼 사용할 수 있습니다.


클로저

JavaScript에서 클로저는 외부 함수가 닫힌 후에도 내부 함수가 외부 범위에 접근하는 개념입니다.

// 외부 함수
function receiveName() {

  // 외부 함수인 receiveName()에 정의된 변수
  let name = 'Hi!';
  
  // 내부 함수
  function showName() {
    // 외부 함수에 정의된 name 변수를 접근합니다.
    console.log('name: ' + name);
  }
  
  // 내부 함수 반환
  return showName;
}

const func = receiveName();
console.log(func); // 함수 정의문
func(); // 함수 호출

실행 결과

ƒ showName() {
    // 외부 함수에 정의된 name 변수를 접근합니다.
    console.log('name: ' + name);
  }
name: H1!

 

다음 예제는 인수가 존재하는 클로저 예시입니다.

function receiveGender(gender) {
  function showName(name) {
    return name + ' is ' + gender;
  }
  return showName;
}

const showMale = receiveGender('male');
const showFemale = receiveGender('female');

console.log(showMale('홍길동'));
console.log(showMale('마이콜'));
console.log(showFemale('이혜리'));

실행 결과

홍길동 is male
마이콜 is male
이혜리 is female

위 예제에서 receiveGender() 함수는 한 개의 인수를 가지며, 내부에 정의된 showName() 함수를 반환합니다. showName() 함수는 한 개의 인수를 가지며, 조합된 문자열을 반환합니다.

 

showMale과 showFemale는 클로저입니다.

 

클로저인 showMale과 showFemale은 showName() 함수를 참조하므로 함수처럼 사용할 수 있습니다.


데이터 프라이버시

JavaScript의 클로저는 데이터를 보호하는데 유용합니다.

let num = 0;

function sum() {
    function increaseSum() {
        return num = num + 1;
    }
    return increaseSum;
}

const increase = sum();
console.log(increase());
console.log(increase());
console.log(increase());

num = num + 1;
console.log(num);

위 예제에서 sum() 함수는 increaseSum() 함수의 정의문을 반환합니다.

 

sum() 함수 외부에 정의된 num 변수는 increaseSum() 함수 내부에서 1씩 증가합니다. 여기서 num 변수는 increaseSum() 함수 외부에서도 변경할 수 있다는 문제가 발생합니다.

 

다음 예제는 increaseSum() 함수가 sum() 함수 외부에 존재하는 변수 num의 값을 변경하지 않습니다.

function sum() {
    let num = 0;
    
    function increaseSum() {
        return num = num + 1;
    }
    
    return increaseSum;
}

const increase = sum();
let num = 10;

console.log(increase());
console.log(increase());
console.log(increase());
console.log(num);

실행 결과

1
2
3
10

정리

  • 함수 내부에 함수가 존재하는 경우 클로저가 생성됩니다.
  • 클로저는 함수가 외부 함수의 범위에 접근할 수 있음을 의미합니다.
반응형

댓글