
함수 내부에서 선언된 지역 변수는 함수가 호출되면 생성되고 함수가 종료하면 소멸.
지역 변수의 생명 주기는 함수의 생명 주기와 대부분 일치.
function foo() {
var x = 'local'; // 변수 x 생성/할당
console.log(x);
return x; // 변수 x 소멸
}
foo();
console.log(x); // ReferenceError: x is not defined
호이스팅은 스코프를 단위로 동작함.
var x = 'global';
function foo() {
console.log(x); // undefined
var x = 'local';
}
foo();
console.log(x); // global
var 키워드로 선언한 전역 변수는 전역 객체의 프로퍼티가 됨. (전역 변수의 생명주기가 전역 객체의 생명 주기와 일치)※ 전역 객체: 코드가 실행되기 이전 단계에 JS엔진에 의해 어떤 객체보다도 먼저 생성되는 특수한 객체.
클라이언트 사이드: window, 서버사이드: global
전역 객체는 표준 빌트인 객체(Object, String, Number, Function, Array, ...)와 환경에 따른 호스트 객체, var 키워드로 선언한 전역 변수와 전역 함수를 프로퍼티로 갖음.
함수 정의와 동시에 호출되는 즉시 실행 함수는 단 한번만 호출됨.
모든 코드를 즉시 실행 함수로 감싸면 모든 변수는 즉시 실행 함수의 지역 변수가 됨.
(function () {
var foo = 10; // 즉시 실행 함수의 지역 변수
}());
console.log(foo); // ReferenceError: foo is not defined
주로 라이브러리에서 사용됨.
전역에 네임스페이스 역할을 담당할 객체를 생성하고 전역 변수처럼 사용하고 싶은 변수를 프로퍼티로 추가하는 방법.
네임스페이스 객체에 또 다른 네임스페이스 객체를 프로퍼티로 추가해서 계층적으로 구성 가능.
var MYAPP = {}; // 전역 네임스페이스 객체
MYAPP.person = {
name: 'Lee',
address: 'Seoul'
}
console.log(MYAPP.person.name); // Lee
※ 캡슐화: 객체의 상태를 나타내는 프로퍼티와 프로퍼티를 참조하고 조작할 수 있는 동작인 메서드를 하나로 묶는 것.
객체의 특정 프로퍼티나 메서드를 감출 목적으로 사용하기도 하는데 이를 정보 은닉이라 함.
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.decrease()); // 0npm run dev시, Vite는 번들링을 하지 않음.npm run build시 성능을 위해 코드를 하나(또는 몇 개)의 파일로 합침. 이를 번들링이라 함.
번들러는 파일을 합치면서 모듈 스코프가 유지되는 것처럼 코드를 변형.
예시:
// bundle.js (함수 껍데기를 벗기고 하나로 합침)
// a.js의 내용
var x$1 = 1; // 충돌을 피하기 위해 뒤에 $1을 붙임
// b.js의 내용
var x$2 = 2; // 여기는 $2를 붙임
console.log(x$1 + x$2);
결과: 겉으로 보기엔 그냥 쭉 이어진 코드 같지만, 번들러가 식별자를 바꿔달아서 논리적 모듈 스코프(격리)를 유지시킴.
결론: 형태는 달라졌지만, 외부와 격리시킨다는 모듈 패턴 철학은 그대로 구현됨.