🍊안녕하세요. 오늘도 감사합니다 🍊
오늘은 클로저에 대해 알아보겠습니다 !
클로저에 대해 본격적인 설명에 들어가기에 앞서 말씀드리자면, 클로저는 정보 은닉 개념과 연관이 있습니다. 클로저를 사용하면 궁극적으로는 데이터 보호를 할 수가 있게 됩니다.
클로저는 무엇이며 클로저가 어떻게 데이터를 보호하는 역할을 하는 것인지 함께 알아봅시다.

이 코드는 우선 클로저와는 관계가 없는 일반 코드입니다.
onlyname함수가 보이고요, 들여다보니 name 매개변수 하나를 받아 바로 콘솔 출력해주는 함수네요. 자, 여기서 저희가 onlyname 함수를 호출한 후에 onlyname 함수 속 age 변수값에 접근하여 변경할 수 있는 방법이 있을까요? 당연히 없습니다. onlyname() 함수 실행이 끝남과 동시에 지역변수인 age에는 더 이상 접근할 수 없게 되니까요. 몇 몇 프로그래밍 언어는 이처럼 항상 함수 안의 지역변수들이 그 함수가 처리되는 동안에만 존재하며, 함수의 소멸과 동시에 소멸됩니다. 그러나 javascript에서는 예외가 있습니다. javascript의 함수는 "클로저(closure)"를 형성할 수 있기 때문입니다. 클로저가 도대체 무엇일까요? 🤔 아래의 코드를 봅시다.

📍
inner 함수를 return값으로 반환해주는 함수 createcount가 보입니다. createcount함수를 호출한 후 그 반환값을 count변수에 할당하고 있으므로, count변수에 inner함수를 할당한 것과 같습니다. 그러니까 지금부터 count()를 호출하면 inner함수의 역할이 실행될 것입니다. 그런데 잠시만요, inner함수에는 count변수가 들어있습니다. 그리고 이 count변수는 createcount함수에서 선언되었던 지역변수였는데, 이미 createcount 함수는 실행이 완료되었죠(return값인 inner함수를 이미 반환해줬고, 함수는 원래 return값을 반환함과 동시에 실행이 끝나니까요.). 그렇다면 더 이상 count변수는 사용할 수 없어야 합니다.
그런데 놀랍게도 count() 함수를 호출할 때마다 count++; 연산자가 매번 1회씩 업데이트되며 정상적으로 출력됩니다. 분명 count변수에 접근할 수 없을텐데 어떻게 count 변수값은 계속 1씩 증가시킬 수 있는 걸까요? 이게 뭔가요? 🫨
📌 클로저 (closure) : 함수가 자신이 선언될 당시의 환경(context)을 기억하여, 함수가 다른 곳에서 호출되어도 해당 환경에 접근할 수 있게 하는 것. 말이 어려운데, 쉽게 말하자면 내부함수가 외부함수의 맥락(context)에 접근할 수 있는 것. 즉, 내부함수가 외부함수의 지역변수 등에 접근할 수 있는 것을 말합니다. 😮
앞서 살펴본 코드에서 내부함수였던 inner함수가 계속해서 외부함수의 지역변수인 count 에 접근할 수 있었던 것도 이 덕분이었던 것이죠.

📍
이 코드도 마찬가지입니다. outter()함수를 호출하면, 최종적으로는 inner함수가 실행되게 되는데 이 때 inner함수에서는 title 변수에 자연스럽게 접근하여 사용합니다. 이미 outter함수의 실행은 완료되었음에도, 내부함수에서 외부함수의 지역변수를 참조할 수 있으니 말이죠.

📍
이번에도 외부함수와 내부함수가 보입니다. makeAdder함수를 호출하면 x+y 기능을 수행하는 익명의 내부함수를 반환해주는 방식이네요. 외부에서 makeAdder(3)을 호출하였는데, 이로서 x=3은 makeAdder함수의 지역변수로 들어가게 됩니다. (매개변수는 함수 안에서 지역변수로 사용되기 때문) . 이 때 내부함수는 외부함수의 지역변수를 참조할 수 있으므로 변수 a의 모습은
const a = function(y) { return 3+y; } 가 되겠네요. 최종적으로 a(2)는 3+2=5이므로 콘솔창에는 5가 출력됩니다. ✍🏻
이쯤 왔으니 아마도 여러분들은 클로저에 대한 감이 잡히셨을 것입니다. '아 ~ 내부함수는 외부함수의 지역변수 등에 접근할 수 있다는 뜻이구나. ' . 🔫 그런데 궁극적으로 이게 무슨 의미가 있길래 배우는 걸까요?
제가 글의 서두에 " 클로저는 정보 은닉 개념과 연관이 있습니다." 라는 말씀을 드렸었죠 !? 🤐

아까 함께 살펴본 코드를 다시 한번 가지고 와 보았습니다.
🧐💭
이런 상황을 가정해 보겠습니다. 제가 과제 체크 앱📱을 만들었어요. 학생이 과제를 완료하였을 때마다 앱에 완료 횟수가 자동으로 카운팅되도록 하려고 해요. 📋✔️이 때 위 코드를 사용하여 학생이 과제 하나를 마쳤을 때마다 count()함수가 자동으로 호출되도록 코드를 짜 두면 되겠죠. 그런데 어느 불량 학생이 과제를 여러 번 하기가 귀찮아 count횟수를 임의로 조작하여 늘리려고 하네요. 과연 성공할 수 있을까요? 🤔 안타깝게도 불가능합니다. 😇 createcount함수를 호출하더라도 그저 횟수가 업데이트된 count변수값의 inner함수가 반환될 뿐, count변수 자체에 접근하여 값을 변경하거나 수정할 수는 없습니다. 왜냐하면 count변수는 createcount함수의 지역변수이기 때문입니다. 외부에서 count변수 자체에 대한 접근이나 수정이 절대 불가능한 구조인 것입니다. ❌
이처럼 💡 외부에서 접근하거나 조작할 수 없는 private한 변수를 함수 내에 생성하고 싶을 때 💡우리는 클로저(closure)를 사용하여 데이터를 보호하고 은닉할 수 있게 됩니다 ! 🤐✔️
오늘은 javascript의 클로저(closure)를 알아보았습니다.
읽어주셔서 감사합니다. 행복한 하루 되세요 ! 🍀🌿
'javascript' 카테고리의 다른 글
[javascript] async, await (7) | 2024.03.15 |
---|---|
[javascript] 유용한 객체 메소드 / 숫자 메소드 총정리 (5) | 2024.03.13 |
[javascript] 비동기 처리(callback, Promise) (3) | 2024.03.08 |
[javascript] 클래스(class)란 무엇인가? (31) | 2024.03.04 |
[javascript] 상속, 프로토타입(prototype) (30) | 2024.03.03 |