๋ชฉ์ฐจ
JS์ ํธ์ด์คํ ์ ๋ํด์ ์์ธํ ์์๋ณด์๋ค!
1. ํธ์ด์คํ ์ด๋?
( 1 ) ํธ์ด์คํ (Hoisting)์ด๋ ๋ฌด์์ผ๊น
JavaScript์์ ํธ์ด์คํ (hoisting)์ด๋, ์ธํฐํ๋ฆฌํฐ๊ฐ ๋ณ์์ ํจ์์ ๋ฉ๋ชจ๋ฆฌ ๊ณต๊ฐ์ ์ ์ธ ์ ์ ๋ฏธ๋ฆฌ ํ ๋นํ๋ ๊ฒ์ ์๋ฏธํฉ๋๋ค.
- MDN (https://developer.mozilla.org/ko/docs/Glossary/Hoisting)
MDN ๋ฌธ์์์๋ ์์ ๊ฐ์ด ๋ฒ์ญ์ ํ์๋ค.
์ฆ, JS์ ์ธํฐํ๋ฆฌํฐ๊ฐ ์ฝ๋๋ฅผ ์ฝ๊ธฐ ์์ํ ๋ ์ ์ธ๋ ๋ณ์, ์์, ํจ์ ๋ฑ์ ๋ชจ๋ ๋ฏธ๋ฆฌ ํ ๋น์ ํ๋ ์์ ์ ์๋ฏธํ๋ค.
๊ธ์ ๋ณธ๊ฒฉ์ ์ธ ์์์ ์์
๋ชจ๋ ์๋ณ์(๋ณ์, ํจ์, ํด๋์ค ๋ฑ)๋ ํธ์ด์คํ ์ด ๋๋ค!
( 2 ) var์ ํน์ง
JS์์ ๋ณ์, ์์๋ฅผ ์ ์ธํ๋ ๋ฐฉ๋ฒ์ 3๊ฐ์ง๊ฐ ์๋ค.
1.var 2.let 3. const
์ด ์ค const๋ ์์๋ฅผ ์ ์ธํ๊ณ var๊ณผ let์ ๋ณ์๋ฅผ ์ ์ธํ๋ค.
๊ทธ๋ ๋ค๋ฉด ์ด ๋์ ์ฐจ์ด๋ ๋ฌด์์ผ๊น? ํธ์ด์คํ ์ ๊ด์ ์์ ์์๋ณด์
์์ 1) var
console.log(a);
var a = 1;
>>> undefined
์์ 2) let
console.log(a);
let a = 1;
>>> Uncaught ReferenceError: a is not defined
์์ ๊ฒฐ๊ณผ๋ฅผ ๋ณด๋ฉด var๋ฅผ ์๋ฌ๋ฅผ ๋ฐํํ์ง ์์ง๋ง let์ ์ฐธ์กฐ์๋ฌ๋ฅผ ๋ฐํํ๋ค.
์ด๋ var๊ณผ let์ ํธ์ด์คํ ์ด ๋ค๋ฅด๊ธฐ ๋๋ฌธ์ ๋ฐ์ํ ๊ฒฐ๊ณผ์ด๋ค.
( 3 ) JS ์ฝ๋ ์คํ์ ๊ธฐ๋ณธ ๊ฐ๋ ๋ค
1) Execution Context (์คํ ์ปจํ ์คํธ)
Execution Context๋ JS์์ ์ฝ๋๊ฐ ์ ์์ ์ผ๋ก ์๋ํ ์ ์๋๋ก ์ํํ๊ฒฝ์ ๋ํ ์ฌ๋ฌ ์ ๋ณด๋ฅผ ๊ฐ์ง๊ณ ์๋ ๊ฐ์ฒด๋ผ๊ณ ํ ์ ์๋ค.
An execution context is a specification device that is used to track the runtime evaluation of code by an ECMAScript implementation.
- ECMAScript(262) 9.4 Execution Contexts
์ฆ, ECMAScripts์์ ์ฝ๋ ์ํ(evaluation) ๋งค์ปค๋์ฆ์ ํํํ๊ธฐ ์ํ ๊ฒ์ด๋ผ๊ณ ํ๋ค.
2) Lexical Environment
์์ Execution Context์ ์ํด์๋ ์์์ด๊ณ ,
์ฝ๋์์ ์ฌ์ฉ๋๋ ๋ณ์, ์์, ํจ์ ์ ์ธ๋ถ๋ค์ด ์ ์ฅ๋๋ ๊ฐ์ฒด์ด๋ค.
์ฆ, ๋ณ์๋ ํจ์๋ฅผ ์ ์ธ ์ด์ ์ ํธ์ถํ ์ ์๋๋ก ํ๋ ๊ฒ์ด๋ค.
์ด๋ก์ธํด '์ฝ๋์ ์์ชฝ์ผ๋ก ๋ณ์์ ํจ์๋ค์ด ๋์ด์ฌ๋ ค์ง๋ค!' ๋ผ๊ณ ์ด์ผ๊ธฐํ๋ ๊ฒ์ด๋ค.
Lexical Environment์ ๊ตฌ์กฐ๋ ์๋ณ์์ ๊ฐ์ ํํ๋ก ์ด๋ฃจ์ด์ง๋ค.
// ์ดํด๋ฅผ ๋๊ธฐ์ํ ์์
lexicalEnvironment = {
Identifier : value,
Identifier : <Function>,
...
}
๋ฐ๋ผ์ ์ฐ๋ฆฌ๊ฐ ์ฝ๋๋ฅผ ์คํ์ํจ๋ค๋ฉด
say();
function say(){
console.log('Hello');
}
์์ ๊ฐ์ด ์ ์ธ๋ถ๊ฐ ํธ์ถ๋ถ๋ณด๋ค ๋จผ์ ์์นํด ์๋๋ผ๋
lexicalEnvironment = {
say : <Function>,
}
Lexical Environment์ ์ ์ฅ์ด ๋๊ณ
์ฝ๋ ์คํ ์ say()๋ผ๋ ํธ์ถ๋ถ๋ฅผ ์ฝ์์ ๋ ์ด๋ฅผ ์ฐธ์กฐํ์ฌ ํจ์๋ฅผ ์คํ์ํจ๋ค.
( 4 ) var์ ํธ์ด์คํ
var์ ์์์ ์ดํด๋ณด์๋ฏ์ด ๋ค๋ฅธ ์ ์ธ๋ฐฉ์๊ณผ ๋ค๋ฅด๋ค.
Scope์ ๊ฐ๋ ๋ ๋ชจํธํ๊ณ , ํธ์ด์คํ ์ ํตํด ์๋ฌ๋ฅผ ๋ฐํํ์ง ์๋๋ค.
์ด๋ฌํ ํน์ง์ ์์ธ์ ๋ฐ๋ก Lexical Environment์ ์ ์ฅ์ด ๋๋ ๋ฐฉ์์ด ๋ฌ๋ผ์์ด๋ค.
์ ๋ต๋ถํฐ ๋งํ์๋ฉด var๋ก ์ ์ธ๋ ๋์์ ๊ทธ ์ฆ์ undefined๋ก ์ด๊ธฐํ๊ฐ ๋๋ค.
์ด์ ๋ํด ์์ธํ ์์๋ณด๊ธฐ ์ํด ํ ๊ฐ์ง ๊ฐ๋ ์ ๋ํด์ ๋ ์์๋ณด์.
( 5 ) Temporal Dead Zone; TDZ
TDZ๋ ์ฝ๋์ ๋ณ์, ํจ์๋ค์ด ์ ์ธ์ด ๋์ด Lexical Environment์ ์ ์ฅ๋ ํ ์ด๊ธฐํ๊ฐ ๋๊ธฐ ์ ๊น์ง์ ์ฃฝ์ ์กด์ ๋งํ๋ค.
์ฆ, ์ ์ธ๊ณผ ์ด๊ธฐํ ์ฌ์ด์ ์ผ์์ ์ผ๋ก ์ฃฝ์ ์ํ๋ฅผ ์๋ฏธํ๋ค.
ํฌ์ธํธ๋ ์ ์ธ๊ณผ ์ด๊ธฐํ ์ฌ์ด์ธ๋ฐ ์์์ ๋งํ๋ฏ var์ ์ ์ธ ์ฆ์ undefined๋ก ์ด๊ธฐํ๊ฐ ์งํ๋๋ค.
ํ์ง๋ง ๋ค๋ฅธ ์ ์ธ๋ค์ ๋ชจ๋ uninitialized ๋ก ์ด๊ธฐํ๋๋ค.
์์)
console.log(a);
var a = 1;
console.log(b);
let b = 2;
lexicalEnvironment{
a : undefined,
b : <uninitialized>,
}
์ด๋ฌํ ํํ์ด๋ค.
undefined๋ ์ค์ง์ ์ธ ๊ฐ์ผ๋ก ์ธ์ํ์ง๋ง
uninitialized๋ ๊ทธ๋ ์ง ์๊ธฐ ๋๋ฌธ์ ์ค๋ฅ๋ฅผ ๋ฐํํ๋ ๊ฒ์ด๋ค.
2. ํํ์๋ค์ ํธ์ด์คํ ์ด ์๋๋ค!
์ ์ธ์ ๊ณง๋ฐ๋ก ํ์ง์๊ณ ๋ณ์์ ์ ์ฅํ๋ ํํ๋ฅผ ๊ฐ์ง๋ ํจ์ ํํ์์ด๋ ํด๋์ค ํํ์์ ํธ์ด์คํ ์ด ์ด๋ฃจ์ด์ง์ง ์๋๋ค.
var๊ณผ ๊ด๊ณ์์ด ๋ถ๊ฐํ๋ค.
์์)
a();
var a = function(){
console.log('Hello');
}
>>> Uncaught TypeError: a is not a function
์์ ๊ฐ์ด ํจ์ํํ์์์ ํธ์ถ์ ๋จผ์ ํ ๊ฒฝ์ฐ TypeError๋ฅผ ๋ฐํํ๋ค.
์ด๋ฅผ ํตํด ์ ์์๋ ๊ฒ์ var ์ด๋ผ๋ ๋ณ์๋ก ํธ์ด์คํ ์ด ๋์์ง๋ง
a()๋ผ๋ ์ฝ๋๋ฅผ ํตํด ํจ์ํธ์ถ์ ์์ฒญํ์๊ธฐ ๋๋ฌธ์ TypeError๋ฅผ ๋ฐํํ๋ค.
ํด๋์ค ํํ์๋ ๋์ผํ ์ด์ ๋ก ํธ์ด์คํ ์ด ๋์ง ์๋๋ค.
์ต์ข ์ ๋ฆฌ
๋ชจ๋ ์๋ณ์๋ค(๋ณ์, ํจ์ ํด๋์ค)์ ํธ์ด์คํ ์ด ๋ฐ์ํ๋ค!
ํ์ง๋ง
var์ undefined๋ผ๋ ๊ฐ์ผ๋ก ์ฆ์ ์ด๊ธฐํ๊ฐ ๋์ด ์๋ฌ๋ฅผ ๋ฐํํ์ง ์๊ณ ,
๋๋จธ์ง let, const ๋ฑ์ uninitialized๋ผ๋ ๊ฐ์ด ์๋ ๊ฒ์ผ๋ก ์ด๊ธฐํ ๋์ด
TDZ์ ๋น ์ง๊ณ ReferenceError๋ฅผ ๋ฐํํ๋ค.
๋ํ ํจ์ํํ์, ํด๋์ค ํํ์์ ํธ์ด์คํ ์ด ๋ฐ์ํ์ง ์๋๋ค!
์ถ์ฒ
https://blinders.tistory.com/90
https://dkje.github.io/2020/08/30/ExecutionContext/
'๐ | WEB DEV > Vanilla JS' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
JS_๊ธฐ๋ณธ ๋ฌธ๋ฒ (26)_ ์ ๊ทผ์ ํ๋กํผํฐ์ privateํ๋ (0) | 2023.04.10 |
---|---|
JS_๊ธฐ๋ณธ ๋ฌธ๋ฒ (25)_ ํด๋์ค (1) | 2023.04.02 |
JS_๊ธฐ๋ณธ ๋ฌธ๋ฒ (24)_ ์์ฑ์ ํจ์ (0) | 2023.03.31 |
JS_๊ธฐ๋ณธ ๋ฌธ๋ฒ (23)_ ๊ฐ์ฒด + (0) | 2023.03.26 |
JS_๊ธฐ์ (2)_ IIFE(์ฆ์ ์คํ ํจ์ ํํ) (0) | 2023.03.16 |
๋๊ธ