JS - Closure

Dongs·2023년 3월 7일
0

HTML, CSS, JavaScript

목록 보기
6/12

클로저(Closure)란?

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

어떻게 동작할까?

JS-클로저 image

fn2 함수를 fn1 함수에서 호출하였을 때 fn2 에서 참조하려는 변수 l1은 함수 fn1 내에 존재하고 있다.
= "그럼 당연히 fn1에서 fn2를 호출했으니 부모 함수인 fn1에 존재하는 변수 l1을 당연히 fn2에서 참조할 수 있지 않을까?" 라고 생각을 하였다.

그러나 변수 l1을 찾을 수 없다 라는 Reference Error 가 발생하였다. 왜일까?

JS-클로저 image

Call Stack 부분의 fn2 함수를 클릭하여 Scope-Chain을 보자.

fn2 함수 내의 지역스코프, Script 내의 지역스코프를 보게 되면 변수 l1은 존재하지 않는다.

JS-클로저 image

이번엔 fn1 함수Scope-Chain을 보자. fn1 내의 지역스코프에는 변수l1이 존재하고 전역스코프에는 변수 l0 만이 존재한다.

‏‏‎ ‎

이로써 알 수 있는 것은 fn1의 로컬이 fn2의 Scope-Chain에 존재하지 않고 fn2에는 fn2만의 독립적인 로컬이 존재한다. 그 다음에는 전역적인 스코프의 내용만이 들어온다.


따라서 결론은 fn1 함수 내에서 fn2 함수를 호출했다고 하더라도 fn1 함수내에서 정의된 변수를 참조할 수 없다. 만약에 어디에서 호출했느냐에 따라 접근할 수 있는 유효범위가 달라진다면 우리는 그것을 Dynamic scope (동적스코프) 라고 부른다. 그러나 자바스크립트는 Static scope 또는 Lexical scope(정적스코프) 를 채택하고 있다.

‏‏‎ ‎

JS-클로저 image

이번엔 fn2 함수를 fn1 함수에 넣고 똑같이 실행시켜보았다.

이번엔 참조에러 없이 정상적으로 동작된 것을 볼 수 있다.

다음엔 브레이크포인트를 걸고 Scope 탭을 보았다.

JS-클로저 image

아까는 존재하지 않았던 Closure라는 탭이 로컬스코프와 전역스코프 사이에 생긴 것을 볼 수 있다. Closure 탭 안에는 fn1 함수의 변수 l1 이 기록되어 있다.

‏‏‎ ‎

이렇게 흘러갔다고 말할 수 있다.

  1. fn2 함수 스코프 내에서 변수 l1을 탐색

  2. 없어서 다음 부모 스코프인 fn1을 탐색

  3. fn1에 변수 l1이 존재

  4. fn2에서 fn1 함수 내에 있는 변수 l1 참조.

‏‏‎ ‎

이로써 최종적으로 알 수 있었던 것은 자바스크립트는

어떤 함수가 있을 때 그 함수의 유효범위는 그 함수가 어디서 호출되었느냐가 아니라 어디서 정의되었느냐에 따라 결정된다는 것이다.

함수는 한번만 정의를 할 수 있다. 정적이다고 말할 수 있으며

정적스코프 또는 렉시컬스코프(lexical scope)라고 부른다. 자바스크립트는 정적스코프(static scope)를 채택하고 있다!


JS-클로저 image

위의 코드는 더하기1 이라는 변수에 숫자 1을 매개변수로 넘겨준 더하기함수공장 이라고 하는 함수가 저장되어있다. 이로써 더하기함수공장 이라는 함수는 1이라는 숫자를 동봉하여 가지고 있는 셈이 된 것이다. 그래서 더하기1 이라는 함수에 숫자 1을 매개변수로 넘겨주며 호출을 하게 되면 기존 부모함수 더하기함수공장 이라는 함수에 동봉되어 있던 매개변수 1, 그리고 더하기1 함수에 매개변수로 넘겨준 1의 덧셈값이 덧셈 함수의 리턴값이 되게 되며, 최종적으로 덧셈 함수를 리턴하였으므로 2가 리턴이 된다.

  • 위의 예를 기준으로 언제든지 호출하면 1에 접근할 수 있다 라는 것이 Closure의 최종 개념인 것이다.

출처 - 생활코딩 유튜브

https://www.youtube.com/watch?v=bwwaSwf7vkE


‏‏‎ ‎
‏‏‎ ‎
피드백은 환영입니다!! 항상 발전하려고 하는 미래의 주니어 개발자입니다.

profile
자대고 css 하는 프론트엔드 개발자

0개의 댓글