대충이라도 하자

2021. 11. 29 (Closure in PHP, Closure in JS) 본문

꼬꼬마 개발자 노트/JS

2021. 11. 29 (Closure in PHP, Closure in JS)

Sueeeeee
반응형

기술 부채

 

Closure in JS 

PHP를 공부하면서 나온 개념인데 자바스크립트를 이용한 고난이도의 테크닉을 구사하는데 필수적인 개념으로 활용되는 것 같다. 자바스크립트에서 클로저(closure)는 내부함수가 외부함수의 맥락(context)에 접근할 수 있는 것을 가르킨다. 

자바 스크립트의 특징 중 하나는 함수 안에 함수를 중첩으로 가질 수 있다는 것!

클로저는 이러한 함수의 특징을 이용하는 방법 중 하나이다.  클로저란 특정한 함수에서 자신을 감싸고 잇는 함수의 변수나, 중첩함수 등을 그대로 활용할 수 있게 만들어주는 함수

***함수 안에 선언해 놓은 어떠한 변수를 함수가 끝난 후에도 계속해서 사용하게끔 할 수 있다.

 

예)

funtion add(){

     var counter = 0;

     counter +=1;

}           

add();

add();

add();

=> 세 번을 호출한다고 하더라도 값은 무조건 counter=1이다.

 

하지만!!!

var add = (function add(){

     var counter = 0;

     return function () {

               return counter +=1;

          }

})();

 

add();

add();

add();

 

=> 정상적으로 counter의 값이 3까지 증가를 하게 된다.

지역 변수이지만 그 값을 계속해서 보존해서 사용할 수 있게 된다.

     

Why do we need to use closure?

: 자바스크립트의 변수들은 기본적으로 public으로 되어 있는데 객체 지향 중에서 지향하는 캡슐화의 형태로 만들려면 클로저를 사용해서 구현 가능. 외부에서 counter라는 변수에 접근할 수 없지만 내부에선 접근이 가능하다. (자바에서 private 개념..?) 다른 지역에서 closure 내에서 사용된 변수를 선언해도 closure 내에 있는 것과는 별개의 변수이므로 겹칠 위험도 없다. 

 

 

*** 필수 개념

1. 실행 문맥( Execution context)

2. 어휘적 범위(lexical scope)

3. 함수를 통한 함수 반환( a function that return a function)

4. closure

===========================================

 

1. 실행 문맥(Execution context) - global code & function code

: 처음에 실행하게 되면 global execution context에서 시작

  some variables는 여기 global에서 declared. -> global variables

 

 

When the program calls a function?

1. 새로운 execution context 생성->local execution context

2. 이 execution context에 로컬인 변수들을 가지고 있음

3. 이 new execution context는 execution stack에 던져짐 

 

When a function ends?

1. execution stack에서 로컬 execution context pop off

2. calling context에 return value 보냄

: return value는 object, array, function, boolean, anything 될 수 잇음

: 만약에 return statement가 없으면 undefined가 돌아옴

3. local execution context는 destroyed됨.

 

 

2. 어휘적 범위(lexical scope)

: 자바스크립트의 어려운 점은 어떻게 변수를 찾는 지이다.

local execution context에서 변수를 찾지 못하면 그것의 calling context에서 변수를 찾고

여기서도 찾지 못하면 global execution context에서 변수를 찾는다.

이 마저도 찾지 못하면 변수는 undefined가 된다.

-> function은 그것의 calling context의 변수에 접근할 수 있다. 그리고 이러한 걸 lexical scope이라고 한다.

3. 함수를 통한 함수 반환( a function that return a function)

 

*** ()는 함수를 execute or call 한다는 의미

     그렇기에 line9에서 adder 에는 addNumbers이 할당되지만 실행되지는 않음

     call stack에 new context를 집어넣음

*** addNumbers는 오로지 local execution context에만 존재 

*** function은 function definition도 return 가능

*** 이 때 createAdder()는 call stack에서 제거

*** addNumbers라는 function도 사라지지만 adder라는 변수에 function의 definition이 저장되어 있음

 

 

4. closure

*** console.log(counter)는 undefined라고 출력될 것

*** c1 = 1, c2 = 2, c3 = 3이 된다. 이러한 mechanism을 the closure이라고 한다.

 

1) 새로운 function을 선언하고 변수에 할당하게 되면 function의 definition뿐만 아니라, closure도 같이 저장하게 된다. 

    closure는 function이 생성될 때의 scope에 있는 모든 변수를 포함함다.

2) 변수를 찾을 대, local이나 global도 우리의 백팩인 closure를 먼저 체크한다. 맨처음  counter = 0인 백팩(closure)에 있었기 때문에 사용하고 다시 값을 업데이트한 뒤, 백팩에 집어넣는다.

 

 

=> global scope에 만들어진 function도 closure를 생성한다. but, 어차피 global은 모든 변수에 접근이 가능해 크게 상관이 없다.

 

 

"closure는 백팩으로 생각하세요"

 

참고 자료) 

https://medium.com/dailyjs/i-never-understood-javascript-closures-9663703368e8

 

I never understood JavaScript closures

Until someone explained it to me like this …

medium.com

 

반응형
Comments