본문 바로가기
  • A space that records me :)
Language/JS,JQuery

[JavaScript] 클로저(Closure)

by yjkim_97 2020. 11. 13.

클로저(Closure)란? - MDN에서의 정의

클로저는 독립적인 (자유) 변수를 가리키는 함수이다. 또는, 클로저 안에 정의된 함수는 만들어진 환경을 ‘기억한다’.

“A closure is the combination of a function and the lexical environment within which that function was declared.”
클로저는 함수와 그 함수가 선언됐을 때의 렉시컬 환경(Lexical environment)과의 조합이다.

클로저는 단순히 함수 외부의 변수에 접근 가능한 내부 함수가 아니다.

함수 실행시 외부 변수 접근을 위해, 함수가 선언될 때 메모리에 저장되는 객체이다.

 


 

function outFunc(){
	var reason = "test";
    	var value = "value test";
	return function innerFunc(r){			
		console.log(r + ", " + value);
	}(reason);
}

outFunc();

// result : test, value test

 

outFunc() 함수를 실행하면 outFunc()의 내부 함수인 innerFunc()가 실행된다.

 

outFunc() 함수의 지역변수인 value는 outFunc()의 스코프가 종료되면서 메모리에서 제거된다.

하지만 내부함수 innerFunc()가 선언될 때 outFunc() 함수의 지역변수 value innerFunc()의 클로저 캑체로 남아, innerFunc() 내에서 접근 가능하다. (클로저의 역할이다.)


var out = 'out value'

function outFunc() {
  var inner = 'in value'

  function inFunc(inParam) {
    console.log('out: ' + out)
    console.log('inner: ' + inner)
    console.log('inParam: ' + inParam)
  }

  return inFunc
}

var param = 'this is param'
var outResult = outFunc()
outResult(param)

// out: out value
// inner: in value
// inParam: this is param

// 인용 : https://blueshw.github.io/2017/04/12/javascript-closure/

 

스코프는 함수를 호출할 때가 아니라 함수를 어디에 선언하였는지에 따라 결정된다.
이를 렉시컬 스코핑(Lexical scoping)이라 한다.

위의 예제에는 세가지 스코프가 존재

  1. 전역 스코프
  2. outFunc() 내 지역 스코프 (렉시컬 스코프 : outFunc() 스코프  + 전역 스코프)
  3. inFunc() 내 지역 스코프 (렉시컬 스코프 : inFunc() 스코프 + outFunc() 스코프 + 전역 스코프)

inFunc()는 outFunc()의 내부 함수이므로 렉시컬 스코프를 참조할 수 있다. 

  • outResult는 outFunc() 함수의 실행 결과 값을 리턴 받는다.
  • 다시 말해 outResult는 outFunc() 내의 inFunc()의 실행 결과 값을 리턴 받는다.
  • 이는 outResult는 inFunc()의 함수 자체를 참조하고 있다. outResult에 인자 값을 전달하면 outFunc()의 내부함 부인 inFUnc()의 파라미터에 인자 값이 전달된다.

클로저

  • outFunc() 함수가 선언되었을 때 상위 범위(전역 범위)의 변수들이 클로저 객체로 메모리에 저장된다.
  • (이런 이 유료 함수 내에서 전역 변수에 접근 가능한 것.)
  • outFunc() 함수 내에서 inFunc() 함수가 선언되었을 때 상위 범위(outFunc()의 지역 범위)의 변수들의 inFunc() 함수의 클로저 객체로 메모리에 저장된다.
  • (이런 이유로 inFunc() 내부에서 outFunc()의 클로저 객체로 저장되어 있던 전역 변수 out에 접근 가능하다.)

클로저는 반환된 내부함수가 자신이 선언됐을 때의 환경(Lexical environment)인 스코프를 기억하여 자신이 선언됐을 때의 환경(스코프) 밖에서 호출되어도 그 환경(스코프)에 접근할 수 있는 함수를 말한다.
이를 조금 더 간단히 말하면 클로저는 자신이 생성될 때의 환경(Lexical environment)을 기억하는 함수다

클로저에 의해 참조되는 외부함수의 변수 즉 outerFunc 함수의 변수 x를 자유변수(Free variable)라고 부른다.
클로저라는 이름은 자유변수에 함수가 닫혀있다(closed)라는 의미로 의역하면 자유변수에 엮여있는 함수라는 뜻이다.

-> 내부함수가 유효한 생태에서 외부함수가 종료하여 외부 함수의 실행컨텍스트가 반환되어도, 스코프 체인을 통해 외부함수를 참조할수 있다는 것을 의미한다. 
-> 즉 외부함수가 이미 반환되었어도 외부함수 내의 변수는 이를 필요로 하는 내부함수가 하나 이상 존재하는 경우 계속 유지된다. 이때 내부함수가 외부함수에 있는 변수의 복사본이 아니라 실제 변수에 접근한다는 것에 주의하여야 한다.

 

클로저는 상위 스코프(렉시컬 스코프)의 환경을 스코프 체인을 통하여 참조할 수 있도록 하는 객체이다.

스코프 체인이 정확히 무엇인지 찾아보자.


https://blueshw.github.io/2017/04/12/javascript-closure/

 

[javascript] 클로저(closure)에 대해서 알아보자

자바스크립트 문법 중에 가장 어려운 부분을 꼽으라면 단연 클로저(closure)일것입니다. 저 또한 클로저 개념은 어느정도는 이해하고 있었지만, 정확한 용도와 개념을 설명하라고 하면 명쾌하게

blueshw.github.io

https://poiemaweb.com/js-closure

 

Closure | PoiemaWeb

클로저(closure)는 자바스크립트에서 중요한 개념 중 하나로 자바스크립트에 관심을 가지고 있다면 한번쯤은 들어보았을 내용이다. execution context에 대한 사전 지식이 있으면 이해하기 어렵지 않

poiemaweb.com