본문 바로가기

Frontend/JS

[JS] 클로저를 이용한 정보 은닉 구현(클로저, 렉시컬 스코프 개념)

728x90
일급 객체를 공부하다 보니
렉시컬 스코프, 클로저에 대한 궁금증이 생겨 이에 대해 공부한 기록이다.

Lexical Scope

렉시컬 스코프는 말 그대로 어휘의 범위이다.
변수가 사용 가능한 범위를 알기 위해 어디에서 선언되었는지 고려하는 것을 의미한다.

 JS는 선언자에 따라 다른 렉시컬 스코프를 가진다.

var

전통적인 JS에는 함수 스코프전역 스코프 두 가지만 존재했다.

var 선언자는 선언된 위치에 따라 다른 스코프를 가진다.

  • 함수 내부 : 함수 스코프
  • 함수 외부 : 전역 스코프

함수 외부에서 전역 스코프를 가지기 때문에

아래와 같은 문제가 발생할 수 있다.

if (Math.random() > 0.5) {
	var x = 1;
} else {
  var x = 2;
}
console.log(x);

x는 Math.random() 값에 따라 반환되어야 하는 값이다.

 

하지만 var 선언자에 의해 전역적으로 생성됨에 따라

마지막에 선언된 x의 값인 2가 콘솔에 찍히게 된다.

 

JS는 블록 스코프 변수를 생성할 수 있도록 let과 const를 이용할 수 있다.

let, const

let과 const는 블록 스코프 변수를 생성할 수 있다는 공통점을 가진다.
let은 변경이 가능한 변수, const는 변경이 불가능한 변수를 생성한다.
if (Math.random() > 0.5) {
  const x = 1;
} else {
  const x = 2;
}
console.log(x); // ReferenceError: x is not defined

var 변수를 사용했을 때 일어났던 문제가 해결되었다.

 

const 선언자를 이용해 x를 블록 스코프 변수로 생성함에 따라

Math.random() 값에 의해 x 값이 결정되게 하였다.

 

이번 기록에서 다룰 클로저는 모든 스코프의 변수를 캡처할 수 있다.

Closure

클로저는 함수와 함수가 선언된 어휘적 환경의 조합이다.
function makeFunc() {
	var name = "Mozilla";
function displayName() {
	alert(name);
}
	return displayName;
}

var myFunc = makeFunc();
myFunc();

 

먼저 myFunc 변수는 makeFunc() 함수가 실행됨에 따라

생성되는 displayName 함수의 인스턴스에 대한 참조다. 

displayName 함수의 인스턴스는 변수 name이 있는 어휘적 환경에 대한 참조를 유지한다.

 

요약하면 현재 코드에서 myFunc는 함수 외부에 위치하기 때문에

name 변수를 참조할 수 없다.

하지만, displayName이 어휘적 환경에 대한 참조를 유지하기 때문에

name 변수를 사용할 수 있는 것이다.

정보의 은닉화

클로저를 이용해 정보의 은닉화를 구현할 수 있다.

 

간단한 카운터를 구현해 보자.

함수 외부에서는 카운터의 값이 몇인지 참조할 수 없게 하고 싶다고 가정하자.

var counter = (function() {
	var privateCounter = 0;
	function changeBy(val) {
		privateCounter += val;
	}
	return {
		increment: function() {
			changeBy(1);
		},
		decrement: function() {
			changeBy(-1);
		},
		value: function() {
			return privateCounter;
		}
	};
})();

privateCounter 변수는 counter 함수 내부에서 선언된 변수이므로,

함수 스코프를 가지기 때문에 외부에서 접근할 수 없는 변수이다.

 

오직 privateCounter변수에 대한 참조를 가지고 있는

increment, decrement, value 함수를 통해서만 외부에서 privateCounter 변수에 접근할 수 있다.

 

이처럼 클로저를 통해 private과 같은 기능을 구현할 수 있다.

참고

 

[JS] javascript Closure(클로저) 정리

javascript를 공부하시다 보면 처음으로 '아... javascript 쉽다고 들었는데... 어렵네... 하는 구간이 있다.' 바로 이 Closure를 마주치는 순간이 그 순간 중 하나가 아닐까 생각한다. 오늘은 이 Closure 에

devkingdom.tistory.com

 

 

클로저 - JavaScript | MDN

클로저는 함수와 함수가 선언된 어휘적 환경의 조합이다. 클로저를 이해하려면 자바스크립트가 어떻게 변수의 유효범위를 지정하는지(Lexical scoping)를 먼저 이해해야 한다.

developer.mozilla.org

마치며

기본적인 개념들을 다루다 보니 모르는 개념이 꼬리를 물고 계속해서 생긴다.

하나씩 천천히 다루며 기록할 계획이다.

 

잘못된 정보에 대한 피드백은 환영입니다.

감사합니다.

 

 

 

728x90