스코프 , 호이스팅( hoisting) , TDZ
- 스코프( Scope )
- 호이스팅( hoisting )
- TDZ(Temporal Dead Zone)
1. 스코프(Scope)
스코프(Scope)는 변수 및 함수의 유효 범위를 나타냅니다.
스코프는 코드에서 변수 및 함수에 접근할 수 있는 범위를 결정 하고 변수 및 함수의 충돌을 방지하고 코드의 가독성과 유지 보수성을 향상합니다.
주요한 스코프 유형에는 전역 스코프(Global Scope)와 지역 스코프(Local Scope)가 있습니다.
전역 스코프(Global Scope):
전역 스코프는 코드의 어느 곳에서든 접근할 수 있는 스코프입니다.
전역 스코프에서 선언된 변수 및 함수는 스크립트의 어디서든 사용할 수 있습니다.
전역 스코프에서 선언된 변수는 전역 변수(Global Variable)이라고 합니다.
전역 스코프에서 선언된 함수는 전역 함수(Global Function)로 알려져 있습니다.
지역 스코프(Local Scope):
지역 스코프는 특정 코드 블록(함수 내부 또는 중괄호로 둘러싸인 블록) 내에서만 접근할 수 있는 스코프입니다.
지역 스코프에서 선언된 변수 및 함수는 해당 블록 내에서만 사용할 수 있습니다.
지역 스코프는 블록 스코프(Block Scope)로도 알려져 있습니다.
함수 내에서 선언된 변수 및 함수는 해당 함수의 지역 스코프에 속합니다.
// 전역 스코프
let globalVariable = "I'm a global variable";
function globalFunction() {
// 지역 스코프
let localVariable = "I'm a local variable";
console.log(globalVariable); // 전역 변수에 접근 가능
console.log(localVariable); // 지역 변수에 접근 가능
}
console.log(globalVariable); // 전역 변수에 접근 가능
console.log(localVariable); // ReferenceError: localVariable is not defined
globalFunction();
"globalVariable"은 전역 스코프에서 선언되었으므로 스크립트 어디에서든 접근할 수 있습니다.
"localVariable"은 함수 내에서 선언되었으므로 해당 함수의 지역 스코프에만 접근할 수 있습니다.
전역 변수(Global Variable) , 지역 변수(Local Variable)
전역 변수(Global Variable):
전역 변수는 어떤 함수 안이든, 스크립트의 어느 곳에서든 접근할 수 있는 변수입니다. 전역 변수는 보통 스크립트 전체에서 공유되며, 한 번 선언되면 어디서든 사용할 수 있습니다. 전역 변수는 주로 애플리케이션의 여러 부분에서 공유되는 데이터를 저장하는 데 사용됩니다. 그러나 너무 많은 전역 변수를 사용하면 코드의 가독성과 유지 보수성이 저하될 수 있습니다.
지역 변수(Local Variable):
지역 변수는 특정 함수나 블록(중괄호로 둘러싸인 코드 블록) 내에서만 접근할 수 있는 변수입니다. 지역 변수는 해당 함수나 블록의 스코프 내에서만 유효하며, 다른 함수나 블록에서는 접근할 수 없습니다. 지역 변수는 주로 특정 함수 내에서만 사용되는 데이터를 저장하는 데 사용됩니다. 이는 변수의 스코프를 작게 유지하고 코드의 오염을 방지하는 데 도움이 됩니다.
전역변수
let globalVar = 10;
function fun() {
console.log(globalVar); // 전역 변수에 접근 가능
}
지역변수
function fun() {
let localVar = 20; // 지역 변수 선언
console.log(localVar); // 지역 변수에 접근 가능
}
console.log(localVar); // ReferenceError: localVar is not defined
블록 스코프 ( Block Scope ):
블록 스코프는 중괄호 {}로 둘러싸인 코드 블록 내부에서만 유효한 범위를 의미합니다. let과 const 키워드로 선언된 변수는 블록 스코프를 가집니다.
{
let blockScopedVar = "I am block scoped";
console.log(blockScopedVar); // "I am block scoped"
}
console.log(blockScopedVar); // ReferenceError: blockScopedVar is not defined
blockScopedVar는 블록 {} 내부에서만 유효하며, 블록 외부에서는 접근할 수 없습니다.
2. 호이스팅(Hoisting)
호이스팅(Hoisting)은 코드 실행 전에 변수 및 함수 선언이 메모리에 끌어올려지는 동작을 말합니다.
이것은 코드 내에서 변수와 함수를 선언한 위치와 관계없이 해당 스코프의 맨 위로 끌어올려진다는 의미입니다.
호이스팅은 코드의 이해를 돕고 예기치 못한 동작을 방지하기 위해 이루어집니다.
변수 호이스팅:
var 키워드로 선언된 변수는 선언 부분이 해당 스코프의 맨 위로 끌어올려집니다. 선언된 변수는 초기화되지 않고 undefined로 초기화됩니다.
console.log(x); // undefined
var x = 10;
함수 호이스팅: 함수 선언식(Function Declaration)은 전체가 호이스팅됩니다. 함수 선언식은 선언과 동시에 초기화되므로 함수를 선언하기 전에 호출할 수 있습니다.
fun(); // "Hello, world!"
function fun() {
console.log("Hello, world!");
}
함수 표현식(Function Expression)의 변수 호이스팅: 함수 표현식은 변수가 호이스팅되지만 함수는 호이스팅 되지 않습니다. 즉, 함수 표현식을 변수에 할당하기 전까지는 함수를 호출할 수 없습니다.
fn(); //TypeError: fn is not a function
let fn = function() {
console.log("Hello, world!");
};
이 오류는 "fn"이 함수가 아닌 변수로 처리되었기 때문에 발생합니다. 이는 "fn"이 let 키워드를 사용하여 선언되었으므로 호이스팅에 의해 변수는 선언되었지만 초기화되지 않았기 때문입니다. 즉, "fn"은 변수로 호이스팅 되었으므로 함수로 인식되지 않습니다.
이렇게 되는 이유는 "fn"을 호출한 코드가 함수가 아니라 변수로 처리되기 때문입니다. 함수 표현식을 사용할 때는 변수가 호이스팅되지만 함수는 호이스팅 되지 않기 때문에 변수가 선언되고 초기화되기 전에 해당 변수에 함수를 할당하면 오류가 발생합니다.
올바른 예)
let fn = function() {
console.log("Hello, world!");
};
fn(); // "Hello, world!"
3. TDZ
TDZ(Temporal Dead Zone): 일시적 사각지대, 변수가 선언되고 변수의 초기화가 이루어지기 전까지의 구간
Temporal Dead Zone (TDZ)는 JavaScript에서 let 및 const로 선언된 변수들이 선언되기 전에 액세스 할 때 발생하는 현상을 말합니다. TDZ는 변수가 선언되었지만 아직 초기화되지 않은 상태를 의미합니다.
TDZ는 let과 const가 블록 스코프를 갖는 변수를 도입함에 따라 발생한 것입니다. 이전에는 var로만 변수를 선언할 수 있었는데, var로 선언된 변수는 선언 전에 사용해도 에러가 발생하지 않았습니다.
그러나 let과 const로 선언된 변수들은 선언되기 전에 접근하면 ReferenceError를 발생시킵니다.
자바스크립트의 변수 생성 단계
선언(Declaration): 변수를 실행 컨텍스트의 변수 객체에 등록하는 단계를 의미, 이 변수는 스코프가 참조하는 대상
초기화(Initialization): 실행 컨텍스트에 존재하는 변수 객체에 선언 단계의 변수를 위한 메모리를 만드는 단계, 이 단계에서 할당된 메모리에는 undefined로 초기화
할당(Assignment): 사용자가 undefined로 초기화된 메모리의 다른 값을 할당
선언과 초기화 단계가 따로 이루어 지는 let, const 같은 경우는 TDZ에 영향을 받습니다.
TDZ에 영향을 받는 것
let , const
class
class의 constructor() 내부의 super() (해당 클래스의 contructor에서 super 함수가 호출되기 전까지는 해당 클래스에서 this를 참조하면 에러 발생)
함수 매개변수 (매개변수 선언 전에 참조하면 에러 발생)
TDZ에 영향을 받지 않는 것
var
function (함수 선언식)
import (import 구문)
1. 접근 시 에러 발생:
TDZ에 있는 변수에 접근하면 ReferenceError가 발생합니다. 변수가 선언된 위치부터 초기화될 때까지 변수에 액세스할 수 없습니다.
console.log(x); // ReferenceError: Cannot access 'x' before initialization
let x = 10;
// let 예시
console.log(a); // ReferenceError: Cannot access 'a' before initialization
let a = 10;
console.log(a); // 10
// const 예시
console.log(b); // ReferenceError: Cannot access 'b' before initialization
const b = 20;
console.log(b); // 20
2. 블록 스코프 영향:
TDZ는 블록 스코프 내에서도 적용됩니다. 블록 스코프는 중괄호 {}로 둘러싸인 코드 블록을 의미합니다.
if (true) {
console.log(y); // ReferenceError: Cannot access 'y' before initialization
let y = 20;
}
{
console.log(x); // ReferenceError: Cannot access 'x' before initialization
let x = 3;
console.log(x); // 3
}
3. 호이스팅이 발생하지만 TDZ에 영향을 받음:
let과 const 변수는 호이스팅에 의해 선언 단계로 끌어올려집니다. 그러나 초기화 단계는 호이스팅되지 않습니다. 이로 인해 변수가 선언된 위치부터 초기화되기 전까지는 TDZ에 있게 됩니다.
console.log(z); // ReferenceError: Cannot access 'z' before initialization
let z;
'javascript+es6' 카테고리의 다른 글
[ javascript ] 30. Set, Map ,yield, Symbol (0) | 2024.08.22 |
---|---|
[ javascript ] 28. 예외처리, 비동기 , Promise, async/await (0) | 2024.04.17 |
[ javascript ] 27. BOM ( window, navigator, screen, location, history ) (2) | 2024.04.05 |
[ javascript ] 26. form 요소 (0) | 2024.03.27 |
[ javascript ] 25. 정규표현식 ( 정규식 ) (2) | 2024.03.13 |