이 시리즈는 You Don't Know JS Yet (1판인 You Don't Know JS의 개정판) 을 가지고 스터디를 진행하면서 요약 정리한 글입니다. 내용에 대한 퀴즈도 깃헙 리포지토리에 올리고 있으니 참고하시면 더 도움이 되실 것 같습니다. 내용에 대해 오류가 있거나 궁금하신 점이 있다면 댓글 달아주세요!
당연히 JS를 사용하는데 여러 JS 파일을 작성해 사용하는데, JS가 파일들을 묶는 큰 하나의 런타임 컨텍스트를 만드는 방법은 2가지가 있습니다.
책에서는 총 3가지를 이야기하면서, 한가지 방법으로 처리 과정에서 (webpack과 같은) 번들러를 사용해 여러 파일들을 하나의 파일로 통합해 처리하는 방법을 소개했습니다. 다만 이는 JS에서 직접적으로 처리하지는 않기 때문에 이 분류에서 제외했습니다.
ES Modules를 사용하면 각각의 모듈이 개별적으로 JS 환경에 들어갑니다. 이후 모듈을 사용할 때엔 import
키워드를 사용해 가져올 수 있습니다. 이때는 모듈의 스코프를 공유할 필요가 없기 때문에 더욱 독립적으로 모듈을 다룰 수 있습니다.
var moduleOne = (function one(){
// ..
})();
var moduleTwo = (function two(){
// ..
function callModuleOne() {
moduleOne.someMethod();
}
// ..
})();
ES Module을 사용하지 않거나, 번들러를 사용하지 않을때 파일간 스코프를 만들기 위해선 결국 전역 스코프 (Global scope)을 사용해야 합니다. 위 코드와 같이 moduleOne
과 moduleTwo
처럼 선언을 한다면 값이 Global Scope로 가게 됩니다. 다만 이렇게 사용하는 것을 남용하면 예외가 많이 발생하기 때문에 적절히 사용해야 합니다.
var studentName = "Sungwoo";
function hello() {
console.log(`Hello, ${ window.studentName }!`);
}
window.hello(); // Hello, Sungwoo!
JS는 HTML 안에서 <script>
태그를 사용해도 사용이 가능한데, 그 상황에서 사용된 변수들은 window
전역변수에 저장됩니다.
window.something = 42;
let something = "Kyle";
console.log(something); // Kyle
console.log(window.something); // 42
지난 챕터에서 다뤘던 Shadowing도 window
변수에 적용되기 때문에 일반적으로는 꺼내올 수 없고 이때 window
를 사용해 특정지을 수 있습니다.
이전에 이야기했듯 개발자 콘솔이나 REPL과 같은 환경에서는 JS의 기능을 100프로 활용할 수 없다고 이야기드렸는데, 대표적인 예시가 바로 전역 스코프입니다. 개발 콘솔에서 선언한 변수들은 전역 스코프에 들어가지만 이 전역 스코프는 가상으로 구현된 스코프이기 때문에 의도한 대로 작동하지 않을 수 있습니다.
var studentName = "Kyle";
function hello() {
console.log(`Hello, ${ studentName }!`);
}
export hello; // module-global
ESM을 통해 여러 파일을 하나의 스코프로 관리할 수 있다고 언급했는데, 이때엔 studentName과 hello는 전역 스코프에 있지 않습니다. 대신 import
를 통해 가져올 수 있습니다. ESM은 전역 스코프에 최소한으로 의존할 수 있도록 도와줍니다.
global.studentName = "Kyle";
function hello() {
console.log(`Hello, ${ studentName }!`);
}
hello(); // Hello, Kyle!
ESM과 마찬가지로 Node 환경에서는 선언만 하는 경우 전역 스코프에 변수를 선언할 수 없습니다. 이때 Node에서의 전역변수인 global
을 활용하면 전역 스코프에 변수를 넣을 수 있습니다.
const theGlobalScopeObject =
(typeof globalThis != "undefined") ? globalThis :
(typeof global != "undefined") ? global :
(typeof window != "undefined") ? window :
(typeof self != "undefined") ? self :
(new Function("return this"))();
ES2020에서부터 GlobalThis
가 추가되면서 웹에서 사용한 window
와 Node에서 활용한 global
을 한번에 사용할 수 있습니다. 위 코드는 GlobalThis
의 폴리필입니다.