본문 바로가기

Front-End

[JavaScript] 1타 강사가 알려주는 Closures!! 이젠 알자

자바스크립트를 사용하시는 개발자 여러분은 클로저(Closures)라는 개념을 알고 있으신가요?? 저는 스코프이라는

단어를 찾아서 둘러보다가 스코프라는 개념을 알게 되면서 클로저라는 개념도 같이 알고 있으면 좋겠다 .. 어디선가

들어본 적은 있지만 실제로 따로 찾아본 적은 없어서 이번 블로그를 통해서 클로저를 알아보려고 합니다!! 근데 또 클로저가

프론트엔드 면접 단골 문제라고 하기도 하네요 .. ( 더 열심히 조사를 해야겠군요 .. 🥹 )

 

먼저 클로저라는 개념을 알기 전에 스코프에 대한 내용으로 시작을 하면 좋을 것 같습니다ㅏㅏ!!

 

스코프(Scope) 그게 뭔가 ..?

스코프 한 번씩은 들어보셨나요?? 네 ..? 게임에서 들어봤다구요?? ㅋㅋㅋㅋㅋㅋ 근데 뭔가 느낌은 비슷한 것 같네요 ㅜㅎ

스코프는요 식별자를 접근 규칙에 따른 유효한 범위를 이야기합니다!!

 

여기서 식별자란 ➡️ 변수, 함수, 클래스에 접근할 수 있는 범위 ( 중괄호나 함수에 의해서 범위가 결정이 된다고 하네요 )

스코프는 계층적인 구조를 가지고 있어요 .. 그리하여서 상위에서 하위는 가능하지만 하위에서 상위는 불가능합니다!!

 

스코프의 종류

스코프의 종류는 엄청 다양하게 있는 거 아시나요? 그중에서 몇 개를 소개해드릴까 합니다.

 

1. 블록 스코프

	if (true){
      	consol.log(`block`);
    }
	
	for let i =0; i<3;, i++) {
      console.log(i);
     }
    
	 { 
 	 console.log('Hi! Taerang');
     }

➡️ 위와 같은 형태는 블록 스코프의 존재인데, 람다 표현법도 알려드릴게요!! (중괄호를 기준으로 범위를 결정한다.)

let Parent = user => {
      return user.name;
    }
    // 같은 함수이지만 람다 함수 사용하면 블록 스코프!!
    
    let Parent = function (user) {
      	return user.name;
    }
    // function 키워드를 사용하면 함수 스코프!!
    // 람다 함수와 일반 함수의 가장 큰 차이점이다.

 

 

이해가 조금 가시나요? 람다 함수를 사용할 경우에는 블록 스코프로 구분이 되고 function인 키워드를 사용하면

함수 스코프로 구분이 됩니다!

 

var _ let _ const 키워드 

1_ var, let

var 키워드 같은 경우에는 블록 스코프를 무시하고 함수 스코프만 의지한다. (다만 람다형 블록 스코프는 포함되지 않는다.)

var키워드를 사용한다고 해도 함수 스코프는 주로  let으로 선언된 변수의 접근 범위를 제한하고, 함수 스코프의 최상단위로

선언이 된다. 블록 단위로 스코프를 구분할 때는 let을 추천한다. 예측 가능한 코드를 작성할 수 있음으로!

 

var보다 let을 더 선언하는 이유 ➡️ var는 재선언을 해도 에러가 안 나지만 let은 생김으로 (충돌의 위험을 방지가 가능하다.)

 

2_ const 

뭐 const는 많이들 사용들 하시는 거니까 잘 알고 계실 것 같다. 값이 변하지 않는 상수를 정의할 때 쓰는 키워드이다.  let과

똑같이 블록 스코프를 따르는데 값이 변경되지 않고 재선언을 하지 않기 때문에 코드를 더 안전적이게 짤 수 있다. 굳이 값이

변경되지 않는 변수를 사용할 것이면, const 키워드를 쓰는 것이 좋다. 값을 재할당 할 경우에는 TypeError 발생한다. 

 

정리

let, const는 스코프의 형태는 둘 다 따르나 var는 함수 스코프만 의지한다. (단. 예외 상황도 존재함)

값의 재할당은 const는 불가능하다. 또 재선언을 var만 가능하다.

 

 

스코프라는 개념을 공부하면서 호이스팅에 대한 개념도 공부를 하고 있으면 정말 좋은데요!! 호이스팅을 알려드릴게요!

 

호이스팅이란?

많은 사람들이 호이스팅이 코드를 실행하기 전에 변수 선언/함수 선언을 한 뒤에 스코프의 최상단위로 끌어올리는 것.

이라고 알고 있는 사람들이 많습니다. (뭐 .. 이건 90%? 정답) 정확한 답변은 최상단위로 끌어올리는 것처럼 보이는 현상

(이게 100% 정답이라고 할 수 있습니다!!) 

 

변수 호이스팅

  • 자바스크립트에서는 모든 선언에 호이스팅이 발생을 한다.
  • let, const, class는 호이스팅이 발생하지 않는 것처럼 동작을 한다.
  • var 선언과 다르게 let으로 선언을 하게 될 경우에는 선언문 이전에 선언하면 참조 에러가 발생한다.

 

클로저(Closures)는 뭘까?

JavaScript Closure!!

클로저는 함수와 함수 안에서 선언을 한 어휘적인 환경을 이야기한다고 합니다. 즉 함수와 함수 안에서 관계!!

 

함수 안에서 함수를 한번 더 선언을 할 경우에는 내부 함수에서 외부 함수로 지역변수를 접근할 수 있지만,

외부 함수의 실행이 끝나고 난 뒤에는 외부 함수가 사라진 이후에도 내부 함수가 외부 함수에 접근할 수 있는 것을 뜻합니다.

 

이유는 js 함수가 리턴하고 리턴되는 함수가 클로저라는 개념을 형성하기 때문에 접근이 가능하다. 

 

 

클로저 함수의 장점 ⭐️

  • 데이터 보전이 가능하다 ➡️ 외부 함수의 실행이 끝나도 외부 변수를 사용가능하고, 스코프 안에 가두는 폐쇄성 ⭕️
  • 캡슐화에 용이하다 ➡️ js는 private method라는 형태의 선언 기능이 없어 캡슐화를 클로저를 이용해 구성 ⭕️
    • private method : 같은 클래스 내부의 특정 메서드에서만 해당 메서드를 호출이 가능한 것 (제한적인 접근 ⭕️)
  • 모듈화가 유리하다 ➡️ 클로저 함수를 통한 각각의 변수가 할당을 하게 되면 각자 독립적으로 값을 사용하며 보존 ⭕️

 

클로저를 간단하게 설명하고자 하는 예시를 들어보자

function Naming(){
  const name = 'taerang';
  console.log(name)
}
Naming() //taerang
console.log(name) //error

여기 Naming이라는 함수에 taerang이라는 문자열을 name 변수에 저장을 하였고 나는 그걸 쓰고 싶다.

하지만 Naming()이라는 함수를 실행을 시킨 이후에는 저 Naming 안에 있는 변수 name 'taerang'을 불러와서

쓸 수 없는 것이다. 이런 상황에서 사용할 수 있는 것이 바로 클로저라는 개념이다.

 

function Naming(){
  const name = 'taerang';
  console.log(name)
  return function inner(){
    const greeting = 'hello!'
    console.log(greeting,name)
  }
}
const getTaerang = Naming() //taerang
getTaerang() //hello!Taerang

Naming 함수가 위와 같이 실행이 끝나고 종료되었을 때 Naming이라는 함수가 종료가 되었으니 name이 접근이

안 되는 것이 아니라 이제는 그 아래 있는 inner라는 함수를 통해서 name에 접근이 가능할 것이다. getTaerang()을

호출하게 되면 inner함수가 실행을 하고 inner함수는 외부 함수인 Naming의 함수 환경을 기억을 하고 있기 때문에

greeting함수와 name 함수를 접근할 수 있는 것입니다.

 

 

 

더 자세한 내용은 공식문서를 참고하면 좋을 듯하다!! (아직 저한테는 어려운 내용들이 참 많네요 .. 하하)

 

클로저 - JavaScript | MDN

클로저는 주변 상태(어휘적 환경)에 대한 참조와 함께 묶인(포함된) 함수의 조합입니다. 즉, 클로저는 내부 함수에서 외부 함수의 범위에 대한 접근을 제공합니다. JavaScript에서 클로저는 함수 생

developer.mozilla.org

 

 

느낀 점

클로저 개념 아직도 솔직히 너무 헷갈린다 .. 😅 아직 다른 부분도 잘 모르겠고 클로저의 개념 부분을 공식문서를 토대로

공부를 하면 좋을 것 같다. 근데 js 단골 기술 면접이라고 하니까 꼭 여러분들도 자세하게 공부를 하면 좋겠습니다!!

 

 

오늘도 즐거운 개발 하세요~🩵