클로저 / 랙시컬스코프

Seonhee Kim·2023년 2월 1일

study

목록 보기
1/18

클로저를 알기 위해서는 스코프의 개념을 먼저 이해해야 함

1. 스코프란 ?

변수의 유효범위, 변수가 참조될 수 있는 범위

ex) 전역에 변수 선언 → 전역 변수 a는 어디서든지 참조할 수 있는 전역스코프를 가진다.

var 함수레벨 스코프 / let,const 블록레벨 스코프

 var global = 'global'

	function hi() {
  var local = 'local'
  console.log(global)
}

	hi() // global
console.log(local) // Uncaught ReferenceError: local is not define
  global 변수는 전역스코프를 가지기때문에 hi로 호출된 콘솔에 찍히지만, 
  local이라는 변수는 함수레벨 스코프를 가지기때문에 
  외부에서 참조하려고 하면 참조에러 발생

2. 렉시컬 스코프란 ? (Lexical scope)

함수를 “어디에 선언하였는지” 에 따라 상위 스코프가 결정되는 것.

자바스크립트를 포함한 대부분의 프로그래밍 언어는 렉시컬 스코프를 따르며, 이를 정적 스코프(Static Scope)라고 부르기도 한다.
FYI : 동적 스코프는 랙시컬 스코프와 달리 함수를 “어디서 호출하였는지”에 따라 상위 스코프가 결정된다.

var x = 1;

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

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

foo(); // 1
bar(); // 1
bar에서 참조하는 x는 "상위 스코프" 가 무엇인지에 따라 결정됨
상위 스코프를 알려면 bar 함수가 "어디에 선언되었는지"를 봐야함
bar가 전역에 선언되었으므로 bar의 상위스코프 = 전역 스코프
그래서 상위스코프인 전역스코프에 선언된 x 변수를 참조함

3. 클로저 (closure)

자신이 생성될 때의 환경 (랙시컬 스코프)을 기억하는(=참조하는) 함수
밖에서 호출되어도 그 환경 (스코프)를 기억하여 접근하는 함수를 말한다.

const outerFunc = () => {
  let x = 10;

  // 이 애가 클로저
  const innerFunc = (y) => {
    x = x + y;
    console.log(x);
  
  }

  return innerFunc;
}

const addFunc = outerFunc();
const addFunc2 = outerFunc()
addFunc(5);// 15
addFunc(10); // 25
addFunc(10); // 35

addFunc2(10) // 20
addFunc2(15) // 35

innerFunc의 x는 렉시컬스코프에 의해 outerFunc의 지역변수 x를 참조함
outerFunc은 const addFunc = outerFunc(); 에서 호출된 후 콜스택에서 제거되고, 가비지 컬렉터가 회수해야 할 것 같지만 , innerFunc에서 outerFunc의 x를 참조하기 때문에 회수되지 않는다.

외부함수가 종료되어도, 내부함수가 유효한 상태에서는 외부함수의 x 변수를 참조할 수 있다. 여기서 내부함수 = 클로저

profile
안녕하세요 ~_~

0개의 댓글