Chapter 14 전역 변수의 문제점
in Frontend / Js / Javascript
Problems regarding global variables
14.1 변수의 생명주기
- 생명주기 (Life cycle): 변수가 메모리에 존재하는 기간 (생성부터 소멸까지)
한번 선언된 변수는 프로그램을 종료하지 않는 한 메모리에 계속 존재
지역변수 생명주기: 함수 호출 시 생성, 함수 종료 시 소멸
- 소멸 뒤 호출 시
ReferenceError
발생 - 함수 호출된 직후 hoisting으로 변수 선언부만 끌어올려짐
- 지역변수 생명주기 === 함수 생명주기, but 변수가 더 오래 존재하는 경우 있음 (스코프 해제 안될 때)
- 소멸 뒤 호출 시
hoisting 은 스코프 단위로 동작함!
var x = "global"; function foo() { console.log(x); // undefined !!! (hoisting) var x = "local"; } foo(); console.log(x); // global
전역변수 생명주기
- 특별한 진입점 없이, 명시적 호출 없이 실행됨
- 함수는 마지막 문 또는 Return 문 실행 후 종료, 전역변수는 프로그램 종료 시 소멸
var
로 선언한 전역변수는window
객체의 프로퍼티로 취급됨 (~ ES5)
14.2 전역 변수의 문제점
암묵적 결합 (Implicit coupling)
- 코드 어디서든 수정 가능, 의도치 않은 결과 발생 가능
긴 생명주기 (Long life cycle)
- 메모리 소비, 메모리 누수 발생 가능
- 변수 이름 중복 가능성 높아짐
스코프 체인 상에서 종점에 존재
- 변수 검색 시 가장 마지막에 검색됨 (lexical environment chain)
- 변수 검색 속도 느려짐
네임스페이스 오염 (Namespace pollution)
⚠️ JS 문제점: 파일 분리되어 있어도 전역 스코프 공유함 (ex: index.js, app.js 같은 전역 변수 이름 사용 시 충돌 발생 가능)
14.3 전역 변수 사용 억제 방법
- 변수 스코프는 좁을 수록 좋다
즉시실행함수 안에 넣거나, 네임스페이스 객체 (전역으로 사용할 객체) 사용, 또는 모듈 패턴 사용으로 방지 가능
모듈 패턴 (
class
모방)- private, public 멤버 구분 가능
var Counter = (function () { var num = 0; // private return { increase() { return ++num; }, }; })(); console.log(Counter.increase()); // 1 console.log(Counter.num); // undefined
ES6 모듈
- 더는 전역변수 사용 불가
- ES6 모듈: 파일 자체의 독자적인 모듈 스코프를 제공함
var
더 이상 window 객체의 프로퍼티가 아님script 에
type="module"
추가하면 ES6 모듈로 인식함- IE를 포함한 구형 브라우저에선 동작 X
- 브라우저의 ES6 모듈 사용하더라도 transpiler/bundling 필요함 (ex: Webpack, Babel)
2회독 노트
- 변수의 생명주기: 메모리 공간 확보 -> 메모리 공간 해제 -> 가용 메모리풀에 반환되는 시점까지
- local variable: 함수의 생명주기와 같음, except for closures
- \(Q.\) const, let같은 경우는 코드 블록? function-level이 아닌 block-level이니?
- global variable: program의 생명주기와 같음 (코드 로드 후 명시적인 호출 없이 실행)
- var키워드로 선언 시 ES6 module (파일 단위 스코프 제공) 이전에는 전부 window 객체의 프로퍼티로 취급됨
- local variable: 함수의 생명주기와 같음, except for closures
- 전역변수의 문제점
- 암묵적 결합 (Implicit coupling) : 이거 변경할 수 있는 곳이 너무 많아서 위험함. 의도치 않은 변경실수에 더 노출됨
- 긴 생명주기 (Long life cycle) : 메모리 비효율
- 스코프 체인 상에서 종점에 존재 : 식별자 resolution하러 가기 멀고도 험난한 길
- 네임스페이스 오염 (Namespace pollution) : 다른 파일내에서도 전역변수 이름 중복 가능성 높아짐
- 전역변수 사용 억제 방법
- 즉시실행함수 안에 넣거나 (메모리 해제되니), 네임스페이스 객체 (전역으로 사용할 객체) 사용, 또는 캡슐화를 지원하는 모듈 패턴 사용으로 방지 가능