Chapter 4: Aroundthe Global Scope - hochan222/Everything-in-JavaScript GitHub Wiki
JS ์์ง์ด single runtime context์์ ์ด๋ป๊ฒ ํฉ์ณ์ง๊น? Browser-executed applications์์ 3๊ฐ์ง ๋ฐฉ๋ฒ์ด ์๋ค.
- ES ๋ชจ๋์ ์ง์ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ ํ์ผ๋ค์ JS enviroment์ ๊ฐ๋ณ์ ์ผ๋ก ๋ถ๋ฌ์์ง๊ณ , ๊ฐ ๋ชจ๋์ ์ ๊ทผํด์ผํ๋ ๋ค๋ฅธ ๋ชจ๋์ ๋ํ ์ฐธ์กฐ๋ฅผ ๊ฐ์ ธ์จ๋ค.
- ๋น๋ ํ๋ก์ธ์ค์์ ๋ฒ ๋ค๋ฌ๋ฅผ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ ์ผ๋ฐ์ ์ผ๋ก ๋ชจ๋ ํ์ผ์ด ๋ธ๋ผ์ฐ์ ์ JS ์์ง์ ์ ๋ฌ๋๊ธฐ ์ ์ ํจ๊ป ์ฐ๊ฒฐ๋์ด ํ๋์ ํฐ ํ์ผ ๋ง ์ฒ๋ฆฌ๋๋ค.
- ๋ง์ฝ ์ด๋๊ฒ๋ ์๋๋ฉด global scope๊ฐ ๊ทธ ์ญํ ์ ํ๋ค.
var moduleOne = (function one(){
// ..
})();
var moduleTwo = (function two(){
// ..
function callModuleOne() {
moduleOne.someMethod();
}
// ..
})();
์ด๊ฑฐ๋ ๋ฐ์ ๋ณ๋์ ๋ ํ์ผ์ด๋ ๋๊ฐ์ด ์ ์ญ์ผ๋ก ์ฒ๋ฆฌ๋๋ค.
var moduleOne = (function one(){
// ..
})();
var moduleTwo = (function two(){
// ..
function callModuleOne() {
moduleOne.someMethod();
}
// ..
})();
๋ธ๋ผ์ฐ์ ํ๊ฒฝ์์ ๊ฐ๋ณ์ ์ผ๋ก ๋ถ๋ฌ์์ง๋ ๊ฒฝ์ฐ ์ ์ญ ๋ณ์๊ฐ ์ ์ผํ ๊ณต์ ๋ฆฌ์์ค์ด๋ค.
์ ์ญ๋ฒ์๋ ๊ทธ์ธ์๋ ๋ค์๊ณผ ๊ฐ์ ์ญํ ์ ์ํํ๋ค.
- built-ins ์ ๊ณต
- primitives: undefined, null, Infinity, NaN
- natives: Date(), Object(), String(), etc.
- global functions: eval(), parseInt(), etc.
- namespaces: Math, Atomics, JSON
- friends of JS: Intl, WebAssembly
- JS ์์ง์ ํธ์คํ
ํ๋ ํ๊ฒฝ์์ ๊ทธ๊ฒ์ built-ins ์ ๊ณต
- console (and its methods)
- the DOM (window, document, etc)
- timers (setTimeout(..), etc)
- web platform APIs: navigator, history, geolocation, WebRTC, etc.
Node๋ ์ ์ญ์ผ๋ก ์ฌ๋ฌ๊ฐ์ง๋ฅผ ์ ๊ณตํ์ง๋ง require(), __dirname, module, URL(๋ฑ๋ฑ)๋ค์ ๊ธฐ์ ์ ์ผ๋ก global scope์ ์์ง ์๋๋ค.
global scope๋ ํญ์ ์ต์๋จ scope(ํ์ผ์ ๊ฐ์ฅ ๋ฐ๊นฅ์ชฝ ๋ถ๋ถ) ์ผ๊น..? JS environment์ ๋ฐ๋ผ ๋ค๋ฅด๊ฒ ์ฒ๋ฆฌํ ์ ๋ ์๋ค.
var studentName = "Kyle";
function hello() {
console.log(`Hello, ${ studentName }!`);
}
hello();
// Hello, Kyle!
์ผ๋ฐ์ ์ผ๋ก ์นํ์ด์ง ํ๊ฒฝ์์ window ๋ฅผ ํตํด global scope์ ์ ๊ทผ ํ ์ ์๋ค.
var studentName = "Kyle";
function hello() {
console.log(`Hello, ${ window.studentName }!`);
}
hello();
// Hello, Kyle!
๊ทธ๋ฌ๋ ํญ์ ๋ชจ๋ JS ํ๊ฒฝ์์ window๋ฅผ ํตํด ์ ๊ทผ ํ ์ ์๋ ๊ฒ์ ์๋๋ค.
์ ์ฅ์์ ์ค๋ช ํ ์๋์์ผ๋ก ๋ค์๊ณผ ๊ฐ์ ๋ฌธ์ ๊ฐ ๋ฐ์ ํ ์ ์๋ค.
window.something = 42;
let something = "Kyle";
console.log(something);
// Kyle
console.log(window.something);
// 42
let ์ ์ธ์ ์ ์ญ ๋ณ์๋ฅผ ์ถ๊ฐํ์ง๋ง ์ ์ญ ๊ฐ์ฒด ์์ฑ์ ์ถ๊ฐํ์ง ์๋๋ค.
์ด ๋ฌธ์ ๋ฅผ ํผํ๊ธฐ์ํด ์ ์ญ ๋ณ์๋ ํญ์ var, ๊ทธ์ธ ๋ธ๋ก ๋ณ์๋ let๊ณผ const๋ฅผ ์ฌ์ฉํ์.
DOM์์ ์ ์ญ ๋ฒ์์ ๋๋ผ์ด ๋์ ์ค ํ๋๋ id ์์ฑ์ด์๋ DOM ์์๊ฐ ์ด๋ฅผ ์ฐธ์กฐํ๋ ์ ์ญ ๋ณ์๋ฅผ ์๋์ผ๋ก ๋ง๋ ๋ค. ๊ทธ์ธ์๋ window[]๋ก ์ ๊ทผ ํ ์ ์๋ค.
<ul id="my-todo-list">
<li id="first">Write a book</li> ..
</ul>
first;
// <li id="first">..</li>
window["my-todo-list"];
// <ul id="my-todo-list">..</ul>
var name = 42;
console.log(name, typeof name);
// "42" string
name์ window.name์ผ๋ก window์ ๋ฏธ๋ฆฌ ์ ์๋ผ์๋ค. ๋ฐ๋ผ์ ์ฐ๋ฆฌ๋ ์ซ์๋ฅผ ๋ฃ์์ง๋ง ๋ฌธ์์ด๋ก ์ ์ฅ๋๋ ๊ธฐ์ดํ ํ์์ ๋ณผ ์ ์๋ค. ์ด๋ฐ ๋๋ฌธ ๋ช๋ช ๊ฐ์ง๋ฅผ ์ ์ธํ๊ณ ์ ์ ์๋ํ๋ค.
Web Workers๋ ๋ธ๋ผ์ฐ์ JS ๋์์ ๊ธฐ๋ฐ์ผ๋กํ๋ ์น ํ๋ซํผ ํ์ฅ์ผ๋ก, JS ํ์ผ์ด ๊ธฐ๋ณธ JS ํ๋ก๊ทธ๋จ์ ์คํํ๋ ์ค๋ ๋์ ์์ ํ ๋ณ๊ฐ์ ์ค๋ ๋ (์ด์ ์ฒด์ ์ธก๋ฉด)์์ ์คํ๋ ์ ์๋๋ก ํ๋ค.
Web Worker ํ๋ก๊ทธ๋จ์ ๋ณ๋์ ์ค๋ ๋์์ ์คํ๋๊ธฐ ๋๋ฌธ์ ๊ฒฝ์ ์กฐ๊ฑด ๋ฐ ๊ธฐํ ์ค๋ฅ๋ฅผ ๋ฐฉ์งํ๊ธฐ ์ํด ๊ธฐ๋ณธ ์ ํ๋ฆฌ์ผ์ด์ ์ค๋ ๋์์ ํต์ ์ด ์ ํ๋๋ค. ์๋ฅผ ๋ค์ด, Web Worker๋ DOM์ ์ก์ธ์ค ํ ์ ์๋ค. (๋จ, ๋ค๋น๊ฒ์ดํฐ๊ฐ์ ์ผ๋ถ ์น API๋ ๊ฐ๋ฅ)
Web Worker๋ ์์ ํ ๋ถ๋ฆฌ๋ ํ๋ก๊ทธ๋จ์ผ๋ก ์ทจ๊ธ๋ผ์ ๋ฉ์ธ JS ํ๋ก๊ทธ๋จ๊ณผ ์ ์ญ ๋ฒ์๋ฅผ ๊ณต์ ํ์ง ์๋๋ค. DOM ์ก์ธ์ค๊ฐ ์๊ธฐ ๋๋ฌธ์ ์ ์ญ ๋ฒ์์ ์ฐฝ ๋ณ์นญ์ด ์กด์ฌํ์ง ์๋๋ค. Web Worker์์ ์ ์ญ ๊ฐ์ฒด ์ฐธ์กฐ๋ ์ผ๋ฐ์ ์ผ๋ก self๋ฅผ ์ฌ์ฉํ์ฌ ๋ง๋ค์ด์ง๋ค.
var studentName = "Kyle";
let studentID = 42;
function hello() {
console.log(`Hello, ${ self.studentName }!`);
}
self.hello();
// Hello, Kyle!
self.studentID;
// undefined
Developer Tools Console/REPL์ ๊ธฐ์กด ์ฒ๋ฆฌ๋ณด๋ค ๊ฐํธํ๋๊ธฐ ๋๋ฌธ์ ์ค์ ๋์๊ณผ ์ ์ฌํ๊ฒ ์๋ํ๋ค. ์ฃผ๋ก ๋ค์ ์ธ๊ฐ์ง์์ ์ฐจ์ด๊ฐ ๋ ์ ์๋ค.
- global scope ๋์
- ํธ์ด์คํ
- ๊ฐ์ฅ ๋ฐ์์ ์ฌ์ฉ๋ ๋ let๊ณผ const์ ๋์ (๋ธ๋ก ๋ฒ์ ์ ์ธ์)
๋ฐ๋ผ์ Developer Tools Console/REPL์ JS์์ ์ธ์ธํ๊ณ ๋ฏธ๋ฌํ ๋์์ ํ์ธ ํ ๋ ์ ํฉํ ํด์ ์๋๋ค.
ES6์์ module pattern์ ์ง์ํ๋ค. (export๋ฅผ ์ฌ์ฉํด ์กฐ์ ๋๋ค.)
var studentName = "Kyle";
function hello() {
console.log(`Hello, ${ studentName }!`);
}
hello();
// Hello, Kyle!
export hello;
studentName๊ณผ hello์ ์ ์ญ ๋ณ์๊ฐ ์๋๋ค.
Node๋ Node ํ๋ก์ธ์ค๋ฅผ ์์ํ๋ ๊ธฐ๋ณธ ํ์ผ์ ํฌํจํ์ฌ ๋ถ๋ฌ์ค๋ ๋ชจ๋ ๋จ์ผ .js ํ์ผ์ ๋ชจ๋๋ก ์ทจ๊ธํ๋ค. Node ํ๋ก๊ทธ๋จ์ ์ต์์ ๋ ๋ฒจ์ด ์ค์ ๋ก๋ ์ ์ญ ๋ฒ์๊ฐ ์๋๋ค. ์ต๊ทผ ES ๋ชจ๋์ ๋ํ ์ง์์ ์ถ๊ฐํ์ง๋ง, Node๋ ์ฒ์๋ถํฐ ๋ค์๊ณผ ๊ฐ์ "CommonJS"๋ผ๋ ๋ชจ๋ ํ์์ ์ง์ํ๋ค.
function Module(module,require,__dirname,...) {
var studentName = "Kyle";
function hello() {
console.log(`Hello, ${ studentName }!`);
}
hello();
// Hello, Kyle!
module.exports.hello = hello;
}
Node๋ require ()์ ๊ฐ์ ๋ง์ "์ ์ญ"์ ์ ์ํ์ง๋ง ์ค์ ๋ก ์ ์ญ ๋ฒ์์ ์๋ณ์ (์ ์ญ ๊ฐ์ฒด์ ์์ฑ๋ ์๋)๊ฐ ์๋๋ค. ๊ธฐ๋ณธ์ ์ผ๋ก Module (..) ํจ์ ์ ์ธ์ ๋์ด๋ ๋งค๊ฐ ๋ณ์์ ๋น์ทํ๊ฒ ๋ชจ๋ ๋ชจ๋์ ๋ฒ์์ ์ฝ์ ํ๋ค.
Node์์ ์ค์ ์ ์ญ ๋ณ์๋ global์ ํตํด ์ ์ํ๋ค.
global.studentName = "Kyle";
function hello() {
console.log(`Hello, ${ studentName }!`);
}
hello();
// Hello, Kyle!
module.exports.hello = hello;
ES2020์์ JS๋ ๋ง์นจ๋ด globalThis๋ผ๋ ์ ์ญ ๋ฒ์ ๊ฐ์ฒด์ ๋ํ ํ์คํ ๋ ์ฐธ์กฐ๋ฅผ ์ ์ํ๋ค.
๋ํ, ํด๋ฆฌํ๋ก ๋ค์๊ณผ ๊ฐ์ด ์ฌ์ฉ ํ ์ ์๋ค.
const theGlobalScopeObject =
(typeof globalThis != "undefined") ? globalThis :
(typeof global != "undefined") ? global :
(typeof window != "undefined") ? window :
(typeof self != "undefined") ? self :
(new Function("return this"))();