[Codecamp-Week5] JS Closure

·2022년 8월 7일
0

Javascript Closure는 Javascript 기본 동작 원리(?)라고 하는데
기본이라는게 이렇게 어려울 줄이야..?

수업을 들으면서도 어질어질했던 Javascript Closure에 대해 살펴보자

1. Scope

Closure의 개념을 이해하기 위해서는 Scope에 대해 먼저 살펴볼 필요가 있다.

1) Scope란?

Scope란 참조 대상 식별자 (어떤 대상을 다른 대상과 구분하여 식별할 수 있는 유일한 이름)를 찾아내기 위한 규칙이다.

var x = 'global'

function example() {
	var y = 'function scope'
    console.log(x)
}

example()
console.log(x)

이 코드에서는 전역에 선언된 변수 x는 어디에든 참조할 수 있지만, 함수 example 안에서 선언된 변수 y는 함수 example 안에서만 참조할 수 있다.

스코프가 없다면 같은 식별자 이름은 충돌을 일으켜 프로그램 전체에서 하나밖에 사용할 수 없다.

2) Scope 구분

(1) Javascript 관점 구분

[1] Global Scope

Global Scope는 코드 어디에서든지 참조할 수 있다.

[2] Local Scope

Local Scope는 함수 코드 블록이 만든 스코프로 함수 자신과 하위 함수에서만 참조할 수 있다.

(2) 변수 관점 구분

[1] Global Variable

전역에서 선언된 변수로 어디에든 참조할 수 있다.

[2] Local Variable

함수 내에서 선언된 변수로 그 함수와 하위 함수에서만 참조할 수 있다.

3) Scope 살펴보기

(1) var과 let의 차이

var x = 0
{
	var x = 1
    console.log(x) // 1
}
console.log(x) // 1
let y = 0
{
  let y = 1
  console.log(y) // 1
}
console.log(y) // 0

var로 변수 선언 시 중괄호 안 변수와 바깥의 변수가 같은 값을 가지는 것을 볼 수 있다.
이는 Hoisting이란 개념 때문인데, 잠시 Hoisting에 대해 살펴보자!

[1] Hoisting이란?

변수, 함수가 선언되기 전에 변수명, 함수명을 알고 있는 것을 말한다.
var, let, const 모두 호이스팅이 되지만 let과 const는 선언 전까지 변수에 접근이 불가능하다.
(선언 전에 변수 접근을 금하는 것을 TDZ(Temporal Dead Zone)이라고 한다.)

[2] var과 let / const

var은 호이스팅 시 udefined로 변수를 초기화한다.
let과 const로 선언한 변수도 호이스팅 대상이지만, var과 달리 호이스팅 시 undefined로 변수를 초기화하지 않는다. 따라서 변수의 초기화를 수행하기 전에 읽는 코드가 먼저 나타나면 예외가 발생하게 된다.

(2) Lexical Scope (=Static Scope)

[1] Lexical Scope란?

Lexical Scope란 함수를 어디서 선언하였는지에 따라 상위 스코프를 결정하는 것이다.
Javascript를 비롯한 대부분의 프로그래밍 언어는 Lexical Scope를 따른다.
함수를 처음 선언하는 순간, 함수 내부의 변수는 Scope Chain에 의해 자기 Scope와 가장 가까운 상위 범위의 변수를 참조하게 된다.

(함수의 상위 스코프를 결정하는 또 다른 방법으로는 Dynamic Scope가 있다. Dynamic Scope란 함수를 어디서 호출하였는지에 따라 상위 스코프를 결정하는 것이다.)

[2] Lexical Scope 살펴보기

Javascript는 Lexical Scope를 따르므로 아래의 bbb 함수는 전역에 선언되어 bbb 함수의 상위 scope는 Global Scope이다. 따라서 아래에서는 전역 변수 x의 값 1을 두 번 출력하게 된다.

var x = 1

function aaa() {
  var x = 10
  bbb()
}

function bbb() {
  console.log(x)
}

aaa() // 1
bbb() // 1

2. Closure

1) Closure란?

Closure란 내부 함수가 외부 함수의 context에 접근할 수 있는 것을 말한다.
(context는 코드의 실행 환경이라고 할 수 있다.)

2) Closure

function aaa() {
  const apple = 10
  
  function bbb() {
    const banana = 20
    
    console.log(apple)
    console.log(banana)
  }
  
  bbb()
  
  const qqq = 3
}

aaa() // bbb(){
	  //	const banana = 20
      //      
      //    console.log(apple)
	  //	console.log(banana)
	  // }

aaa()() // 20
		// 10
		// 20

aaa() 함수를 호출하면 bbb() 함수 자체를 리턴, aaa()()를 호출하면 bbb() 함수 내부 변수까지 리턴할 수 있다.
bbb() 함수 외부에서 선언된 apple을 bbb() 함수가 접근해 콘솔을 출력하고 있다. 이러한 것을 Closure라고 한다.

위와 같은 과정을 call stack과 scope와 연결하여 확인하려면 이미지처럼 개발자도구-소스에서 closure(중단점)를 설정하여 확인할 수 있다.

<참조 : https://poiemaweb.com/js-scope
https://developer.mozilla.org/ko/docs/Web/JavaScript/Closures>

profile
개발을 개발새발 열심히➰🐶

0개의 댓글