변수의 범위를 최소화 하라
Effective Java Item.57
전역 변수는 말 그대로 전역, 즉 코드 어디서든 참조하고 할당할 수 있는 변수를 사용하겠다는 것이다. 이 말은 전역 변수는 모든 코드가 변경하고 참조할 수 있는 암묵적 결합(implicit coupling)을 허용하게 된다.
변수의 유효 범위는 좁을 수록 좋고, 다 사용한 변수는 스코프 밖으로 밀어내는 것이 제일 바람직하다. 전역 변수는 코드의 가독성을 망치고, 의도치 않게 상태가 변경될 수 있는 위험성을 항상 내포한다.
전역 변수는 프로그램이 종료 될 때 까지 살아있다. 즉 전역 변수는 생명 주기(life cycle, 라이프 사이클)이 길다.
따라서 전역 변수가 많은 프로그램은 프로그램이 종료 될 때까지 많은 자원(resource, 리소스)를 확정적으로 차지하게 되어, 성능 저하를 야기한다.
전역 변수는 스코프 체인 상에서 종점에 존재한다. 이는 가장 상위 스코프에 전역 변수가 존재한다는 것으로, 전역 변수의 검색 속도가 모든 변수 중 가장 느리다는 것을 의미한다.
자바스크립트 세상에서 파일이 물리적으로 분리되어 있다 해도 하나의 전역 스코프를 공유한다. 즉 다른 파일 내에서 동일한 이름으로 명명된 전역 변수나 전역 함수는 예기치 못한 결과를 야기할 수 있다.
함수 정의와 동시에 즉시 호출되는 함수를 즉시 실행 함수(IIFE, immediately invoked function expression)이라 한다.
즉 모든 코드를 즉시 실행 함수로 감싸면, 모든 변수는 즉시 실행 함수의 지역 변수가 된다.
전역에 네임스페이스(namespace) 역할을 담당할 객체를 생성하고, 전역 변수처럼 사용하고 싶은 변수를 프로퍼티로 추가하는 기법이다.
var myNameSpace = {};
myNameSpace.student = {
name : `jong`,
subject : `math`
}
myNameSpace.teacher = {
name : `mingu`,
subject : `english`
}
네임스페이스 객체를 프로퍼티로 추가해, 마치 계층적으로 구성된 네임스페이스로 구현하였다.
Java나 C# 등 대부분의 객체지향 프로그래밍 언어는 클래스를 구성하는 멤버에 대해 접근 제한자(access modifier)로 공개 범위를 한정할 수 있다.
그러나 자바스크립트는 접근 제한자를 제공하지 않는다. 모듈 패턴은 자바스크립트에서 정보 은닉(infomation hiding)과 전역 네임스페이스의 오염을 막는 기능을 구현한다.
var Counter = (function () {
var num = 0;
return {
increase() {
return ++num;
},
decrease() {
return --num;
}
};
}());
console.log(Counter.num); // undefined
console.log(Counter.increase()); // 1
console.log(Counter.increase()); // 2
console.log(Counter.decrease()); // 1
console.log(Counter.decrease()); // 0
위 예제의 즉시 실행 함수의 리턴 타입은 객체이다. 이 때 반환되는 객체의 프로퍼티는 퍼블릭 멤버(public member)이다. 그러나 변수나 함수는 반환하는 객체에 추가하지 않으면 외부에서 접근할 수 없는 프라이빗 멤버(private member)가 된다.
ES6 모듈은 파일 자체의 독자적인 모듈 스코프를 제공하기 때문에 ES6 모듈을 사용하면 전역 변수를 더 이상 사용할 수 없다.
즉 모듈 내에서 var 키워드로 선언한 변수는 전역 변수도 아니며, window 객체의 프로퍼티도 아니다.
<script type="module" src="myJS.mjs"></script>
script 태그에 type 속성(attribute)를 추가하면 로드(load)된 자바스크립트 파일은 모듈로서 동작한다.
모던 자바스크립트 Deep Dive
이웅모 저 | 위키북스 | 2020년 09월 25일