모던 자바 스크립트 Deep Dive 를 읽고 정리한 글 입니다.
14. 1 변수의 생명 주기
변수의 생명주기
메모리 공간이 확보된 시점부터 메모리 공간이 헤제 되어 가용 메모리 풀에 반환되는 시점
변수에 생명 주기가 없다면 한번 생성된 변수는 프로그램을 종료하지 않는 한 메모리 공간 점유
호이스팅
변수 선언이 스코프의 선두로 끌어 올려진 것처럼 동작하는 자바스크립트의 고유 동작
호이스팅은 스코프를 단위로 동작
지역 변수의 생명 주기
- 지역 변수의 생명 주기 = 함수의 생명 주기와 일치
- 함수 호출 직후 함수 몸체의 코드가 순차적으로 실행되기 이전에 자바스크립트 엔진에 의해 실행
대부분 지역 함수의 생명 주기와 함수의 생명 주기가 일치하지만 지역 함수보다 오래 생존 할 수도 있음
function foo() { // 변수 x todtjd
var x = 'local'; // 변수에 값 할당
console.log(x); // => local
return x; // 변수 소멸
}
foo();
console.log(x); // => ReferenceError: x is not defined
var x = 'global';
function foo() { // 지역변수 선언, undefiend로 초기화
console.log(X); // => local
var x = 'local';
}
foo();
console.log(x); // => golbal
전역 변수의 생명 주기
- 전역 코드는 명시적 호출 없이 실행
- 함수 호출과 같이 특별한 진입점이 없고 로드 되자마자 해석 및 실행
- 마지막 문이 실행되어 더 이상 실행할 문이 없을 때 종료
- 전역 변수의 생명 주기 = 전역 객체의 생명주기
- var 키워드로 선언한 젼역 변수의 생명 주기 = 전역 객체의 생명 주기
전역 객체
코드가 실행되기 이전 단계에 자바스크립트 엔진에 의해 어떤 객체보다 먼저 생성된느 특수한 객체
표준 빌트인 객체, 환경에 따른 호스트 객체, var 키워드로 선언한 전역 변수 / 전역 함수를 프로퍼티로 가짐
14. 2 전역 변수의 문제점
암묵적 결합
모든 코드가 전역 변수를 참조하고 변경 할 수 있음.
긴 생명주기
지역변수보다 생명 주기가 김
메모리 리소스 오랜 기간 소비
상태 변경에 의한 오류 변수가 발생할 확률이 큼
스코프 체인 상에서 종점에 존재
변수를 검색할 때 전역 변수의 검색 속도가 가장 느림
네임스페이스 오염
파일이 분리되어 있어도 하나의 전역 스코프 공유로 오류 가능성 있음
14. 3 전역 변수의 사용을 억제하는 방법
전역 변수를 반드시 사용해야 할 이유가 없다면 지역 변수 사용
변수의 스코프 범위는 좁을수록 좋음
즉시 실행 함수
모든 코드를 즉시 실행 함수로 감싸 모든 변수를 즉시 실행 함수의 지역 변수로 만듬
(function () {
var foo = 10; // 즉시 실행 함수의 지역 변수
// ...
}());
console.log(foo); // RefferenceError: foo is not defined
네임 스페이스 객체
전역에 네임 스페이스를 담당할 객체를 생성하고 전역 변수처럼 사용하고 싶은 변수를 프로퍼티로 추가
네임스페이스 객체에 또 다른 네임스페이스 객체 프로퍼티로 추가하여 계층적 구성 가능
var MYAPP = {}; // 전역 네임스페이스 객체
MYAPP.person = {
name: 'Lee'.
address: 'Seoul'
};
console.log(MYAPP.person.name); // => Lee
모듈 패턴
클래스를 모방하여 관련 있는 변수와 함수를 모아 즉시 실행 함수로 감싸 하나의 모듈 생성
자바스크립트의 클로저 기반 동작
전역 변수의 억제, 캡슐화까지 구현 가능
전역 네임스페이스의 오염을 막고 정보 은닉을 구현
캡슐화
객체의 상태를 나타내는 프로퍼티와 프로퍼티 참조 / 조작 가능한 동작인 메서드를 하나로 묶음
정보은닉
객체의 특정 프로퍼티나 메서드를 감춤
퍼블릭 멤버 : 외부에 노출된 객체의 프로퍼티
프라이빗 멤버 : 반환하는 객체에 추가하지 않으면 외부에서 접근할 수 없음
val Counter = (function () {
// private 변수
var num = 0;
// 외부로 공개할 데이터나 메서드를 프로퍼티로 추가한 객체 반환
return {
increase() {
return ++num;
},
decrease() {
return --num;
}
};
}());
// private 변수는 외부로 노출되지 않음
console.log(Counter.num); // => undefined
console.log(Conter.increase()): // => 1
console.log(Conter.increase()): // => 2
console.log(Conter.decrease()): // => 1
console.log(Conter.decrease()): // => 0
ES6 모듈
ES6 모듈은 파일 자체의 독자적 모듈 스코프 제공
-> 전역 변수 사용 불가