[JS] Closure 클로저

김다빈·2023년 8월 29일
0

자바스크립트

목록 보기
23/36
post-thumbnail

📌 클로저

중첩된 함수 그룹에서 내부 함수가 상위 범위의 변수 및 기타 리소스에 액세스 할 수 있음을 의미.

즉, 함수를 어디서 선언하였는지에 따라 상위 스코프를 결정한다는 뜻이며, 가장 중요한 점은 함수를 어디서 호출하는지가 아니라 어디에 선언하였는지에 따라 결정된다.

✴️ 예시 1

var x = 1;

function foo() {
  var x = 10;
  bar();
}

function bar() {
  console.log(x);
}

foo(); // 1
bar(); // 1

클로저는 함수가 어디에서 선언되었는가에 따라 lexical scope가 달라진다. (호출 아니고 선언!!!!!!!!)
foo() 함수bar() 함수 모두 전역 범위에서 선언됨
즉, foo() 함수bar() 함수 의 lexical scope 는 전역 스코프

1) bar() 의 결과가 1인 이유

bar() 함수는 전역 범위에서 선언되었고, 그에 따른 렉시컬 스코프는 전역 스코프이다.

따라서 bar() 함수 내부의 console.log(x)에서 x는 전역 범위에서 선언된 x = 1 을 참조한다.

2) foo() 의 결과가 1인 이유

foo() 함수 내부에서 x를 선언하긴 했지만, bar(); 는 foo() 함수 내부에서 선언된 것이 아니라 호출된 것이기 때문에 실제로 선언된 위치(전역)을 기준으로 x = 1 을 참조한다.

3) 만약 bar() 함수가 foo() 함수 내부에서 선언되었다면?

var x = 1;

function foo() {
  var x = 10;
  
  //bar() 함수 선언!
  function bar() {
    console.log(x);
  }

  bar();
}

foo(); // 10

foo() 함수 내부에서 선언된 bar() 함수의 lexical scope는 foo() 함수이므로 foo() 함수의 변수에 접근할 수 있다.

따라서 bar() 함수 내부의 console.log(x)에서 x는 foo() 함수 범위에서 선언된 x = 10 을 참조한다.

✴️ 예시 2

function createCount() {
  let a = 0;
  return function () {
    return a += 1
  }
}

const count = createCount();
//const count = function () { return a += 1 }

console.log(count()); //1
console.log(count()); //2
console.log(count()); //3

count 함수를 클로저라고 할 수 있다.

별도의 상태 관리를 하지 않아도, 함수 내부에서 누적될 수 있는 특정한 변수를 사용할 수 있고, 이때 클로저라는 개념을 유용하게 사용할 수 있다.

✴️ 예시 3

const h1El = document.querySelector('h1')
const h2El = document.querySelector('h2')

1. 별도의 상태 관리 필요한 변수 사용하는 방법

let h1IsRed = false;
let h2IsRed = false;

h1El.addEventListener('click', event => {
  h1IsRed = !h1IsRed;
  h1El.style.color = h1IsRed ? 'red' : 'black';
})
h2El.addEventListener('click', event => {
  h2IsRed = !h2IsRed;
  h2El.style.color = h2IsRed ? 'red' : 'black';
})

2. 클로저 개념 사용

const createToggleHandler = () => {
  let isRed = false;
  return event => {
    isRed = !isRed;
    event.target.style.color = isRed ? 'red' : 'black';
  }
}

h1El.addEventListener('click', createToggleHandler())
h2El.addEventListener('click', createToggleHandler())
profile
Hello, World

0개의 댓글

관련 채용 정보