전역 변수의 무분별한 사용은 위험 하다.
전역 변수를 반드시 사용해야 할 이유를 찾지 못한다면 지역 변수를 사용하자.
변수
: 선언에 의해 생성되고 할당을 통해 값을 가지며, 언젠가 소멸된다.
→ 변수의 생명주기life cycle
if) 변수에 생명주기가 없다면? 영원히 메모리 공간을 점유하게 된다.
변수는 자신이 선언된 위치 에서 생성되고, 소멸한다.
전역 변수
의 생명 주기 == 애플리케이션의 생명 주기지역 변수
의 생명 주기 == 함수가 호출되면 생성, 함수가 종료하면 소멸function foo() {
var x = 'local';
console.log(x); // local
return x;
}
foo();
console.log(x); // ReferenceError: x is not defined
다만 지역변수가 함수보다 오래 생존하는 경우도 있다.
변수
는 하나의 값을 저장하기 위해 확보한 메모리 공간 자체 또는 그 메모리 공간을 식별하기 위해 붙인 이름이다. 함수 내부에서 선언된 지역 변수는 함수가 생성한 스코프에 등록된다.
변수는 자신이 등록된 스코프가 소멸(메모리 해제)될 때까지 유효하다.
할당된 메모리 공간은 더 이상 그 누구도 참조하지 않을 때 가비지 콜렉터에 의해 해제되어 가용 메모리 풀에 반환된다.
다음 1에서 출력되는 값을 무엇인가?
var x = 'global';
function foo() {
console.log(x); // ①
var x = 'local';
}
foo();
console.log(x); // global
⭕️ Answer
undefined
호이스팅은 변수 선언이 스코프의 선두로 끌어 올려진 것처럼 동작하는 자바스크립트 고유의 특징을 말한다.
전역 코드는 명시적인 호출 없이 실행된다.
전역 코드는 함수 호출과 같이 전역 코드를 실행하는 특별한 진입점이 없고, 코드가 로드되자마자 곧바로 해석 및 실행된다.
함수와 달리, 전역코드는 반환문을 사용할 수 없으므로 마지막 문이 실행되어 더 이상 실행할 문이 없을 때 종료한다.
var
키워드로 선언한 전역변수는 전역 객체의 프로퍼티가 되어, 전역 변수의 생명 주기가 전역 객체의 생명주기와 일치하는 것을 말한다.
var
키워드로 선언한 변수 : 전역 코드 종료 시까지 소멸되지 않으므로, 사용하지 않아도 메모리를 사용하고 있어 메모리가 낭비된다. 암묵적 결합
긴 생명주기
var
키워드는 변수의 중복 선언을 허용하기에, 생명 주기가 긴 전역 변수는 변수 이름이 중복될 가능성이 있다.var x = 1;
// ...
// 변수의 중복 선언. 기존 변수에 값을 재할당한다.
var x = 100;
console.log(x); // 100
스코프 체인 상에서 종점에 존재
네임스페이스 오염
전역 변수를 반드시 사용해야 할 이유를 찾지 못할 경우 지역 변수를 사용해야 한다.
변수의 스코프는 좁을수록 좋다.
모든 코드를 즉시 실행 함수로 감쌀 경우 모든 변수는 즉시 실행 함수의 지역 변수가 된다.
(function () {
var foo = 10; // 즉시 실행 함수의 지역 변수
// ...
}());
console.log(foo); // ReferenceError: foo is not defined
전역에 네임 스페이스 역할을 담당할 객체를 생성하고, 전역 변수처럼 사용하고 싶은 변수를 프로퍼티로 추가하는 방법이다.
var MYAPP = {}; // 전역 네임스페이스 객체
MYAPP.name = 'Lee';
console.log(MYAPP.name); // Lee
var MYAPP = {}; // 전역 네임스페이스 객체
MYAPP.person = {
name: 'Lee',
address: 'Seoul'
};
console.log(MYAPP.person.name); // Lee
모듈 패턴은 클래스를 모방해 관련 있는 변수 및 함수를 모아 즉시 실행 함수로 감싸 하나의 모듈을 생성한다.
모듈 패턴은 자바스크립트의 클로저를 기반으로 동작한다.
전역 변수의 억제 & 캡슐화 구현 가능
캡슐화(capsulation)
: 객체의 상태를 나타내는 프로퍼티와 프로퍼티를 참조 & 조작할 수 있는 동작인 메서드를 하나로 묶는 것객체 지향 프로그래밍 언어에서의 클래스 멤버 접근 제한자
public
, private
, protected
, ... : 공개 범위 한정 접근 제한자public
: 외부에서 접근 가능private
: 내부에서만 사용자바스크립트에는 위와 같은 접근 제한자가 없다.
var Counter = (function () {
// private 변수
var num = 0;
// 외부로 공개할 데이터나 메서드를 프로퍼티로 추가한 객체를 반환한다.
return {
increase() {
return ++num;
},
decrease() {
return --num;
}
};
}());
// private 변수는 외부로 노출되지 않는다.
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
ES6 모듈을 사용하면 더는 전역 변수를 사용할 수 없다.
→ ES6 모듈이 파일 자체의 독자적인 모듈 스코프를 제공하기 때문이다.
type="module"
어트리뷰트 추가 시 로드된 자바스크립트 파일은 모듈로서 동작한다. <script type="module" src="lib.mjs"></script>
<script type="module" src="app.mjs"></script>