fffo
전역변수의 문제점 / let, const 키워드와 블록 스코프 본문
전역 변수의 문제점
변수의 생명 주기
- 변수가 런타임 이전에 선언되는 것은 전역변수 한정
- 지역 변수는 해당 스코프가 실행 될 때 선언되고 스코프가 끝날 때 소멸 됨
- 변수가 할당된 메모리 공간은 누군가가 참조하고 있지 않을 때 가비지 콜랙터에 의해 해제 됨 → 누군가 참조하고 있다면 해제되지 않고 남아있음
- 일반적으로 함수가 종료되면 함수가 생성한 스코프도 소멸하지만 누군가 스코프를 참조하고 있으면 스코프는 해제되지 않고 생존 → 클로저
전역 객체
- 전역 객체 : 코드가 실행되기 이전 단계에 js엔진에 의해 어떤 객체보다도 먼저 생성되는 특수한 객체
- 브라우저 : window
- node.js : global
- 환경에 따라 전역 객체를 가리키는 다양한 식별자(window, self, this, frames, global)가 존재했으나 ES11에서 globalThis로 통일됨
- 전역 객체는 표준 빌트인 객체, 환경에 따른 호스트 객체, var키워드로 선언한 전역변수와 전역 함수를 프로퍼티로 가짐
- 표준 빌트인 객체 : Object, String, Function, Array 등
- 환경에 따른 호스트 객체 : 클라이언트의 Web API, Node.js의 호스트 API
전역 변수의 문제점
- 암묵적 결합 : 모든 코드가 전역 변수를 참조하고 변경할 수 있음
- 긴 생명 주기 : 메모리 리소스를 오래 소비, 의도치 않은 재할당 초래
- 스코프 체인 상에서 종점에 존재 : 변수 검색 시 전역 변수의 검색 속도가 가장 느림
- 네임스페이스 오염 : 파일이 분리되어 있어도 전역 스코프를 공유함
전역 변수의 사용을 억제하는 방법
- 지역변수 이용 지향, 스코프는 최대한 좁게 사용
- 즉시 실행 함수 : 모든 코드를 즉시 실행 함수로 감싸면 모든 변수가 즉시 실행 함수의 지역 변수가 됨 → 라이브러리 등에 자주 사용됨
- 네임스페이스 객체 : 전역에 네임스페이스 역할을 할 객체 생성 후 전역 변수처럼 사용할 변수를 프로퍼티로 추가.
- 네임스페이스 내에 또 다른 네임스페이스 객체를 계층적으로 구성 가능
- 식별자 충돌을 방지할 수 있으나 네임스페이스 객체 자체가 전역 변수에 할당되므로 그리 유용한 방식은 아님
- 모듈 패턴 :
var Counter = (function() {
// private 변수
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
- ES6 모듈 : 파일 자체의 독자적인 모듈 스코프 제공, 전역 변수 사용 불가. 구형 브라우저에서는 동작하지 않음
let, const 키워드와 블록 레벨 스코프
var 키워드로 선언한 변수의 문제점
- 변수 중복 선언 허용
- 중복 선언 시 초기화문이 있으면 js엔진에 의해 var 키워드가 없는 것처럼 동작, 초기화문이 없으면 무시됨
- 함수 레벨 스코프
- 오직 함수의 코드 블록만 스코프만 지역 스코프로 인정
- if문 for문 등 다른 코드 블록은 모두 전역 스코프
- 변수 호이스팅으로 인한 가독성 저하 및 오류 발생 유발
let 키워드
- ES6에서 새로 나온 변수 선언 키워드
- 변수 중복 선언 금지
- 블록 레벨 스코프 적용
let 키워드 변수의 호이스팅
- 변수 호이스팅이 발생하지 않는 것 처럼 동작
- 선언 단계와 초기화 단계가 분리되어 진행
- 런타임 이전에 선언단계가 실행 되지만 undefined로의 초기화는 변수 선언문에 도달 했을 때 실행 됨
- 일시적 사각지대(Temporal Dead Zone; TDZ) : 스코프 시작 ~ 초기화 시작
- 모든 선언은 호이스팅됨. 그러나 let, const, class는 호이스팅이 발생하지 않는 것처럼 동작함
전역 객체와 let
- var 키워드로 선언한 전역 변수, 전역 함수, 암묵적 전역은 전역객체의 프로퍼티가 됨
- 그러나 let으로 선언한 전역 변수는 전역객체의 프로퍼티가 아닌 개념적인 블록 내에 존재
// 브라우저 환경에서 실행
var x = 1;
y = 2; // 암묵적 전역
let z = 3;
console.log(window.x); // 1
console.log(window.y); // 2
console.log(window.z); // undefined
const 키워드
- 주로 상수 선언 시 사용
- let 키워드와 대부분 동일하지만 몇 가지 차이점 존재
- 반드시 선언과 동시에 초기화 해야 함
- 재할당 금지
- 상수의 이름은 대문자로 선언 권장, 스네이크 케이스로 표현 일반적
- const 키워드로 선언된 객체는 재할당이 불가능 할 뿐, 변경 가능함
- 기본적으로 const를 사용하고 재할당이 필요한 변수일 경우만 let을 사용 권장
'Programming > Javascript' 카테고리의 다른 글
생성자 함수에 의한 객체 생성 (0) | 2021.10.01 |
---|---|
프로퍼티 어트리뷰트 (0) | 2021.09.30 |
스코프 (0) | 2021.09.28 |
js 복습 - 깊은복사, 생성자, Date (0) | 2021.09.27 |
함수 (0) | 2021.09.27 |
Comments