#var
우리가 모두 아는 var 키워드는 아래와 같은 특징을 가지고 있습니다.
- 함수레벨 스코프를 가지고 있다.
- 대부분의 프로그래밍 언어들이 블록 레벨 스코프를 사용하고 있지만, var로 선언된 키워드는 함수레벨 스코프를 갖는다.
- var 키워드는 생략이 가능하다.
- 생략이 가능하기 때문에, 함수가 선언한 환경의 this에 영향을 받는다. 일반적인 웹 환경에서는 window일 것이다.
- 중복 선언이 가능하다.
- 호이스팅 당한다.
#let
우리가 모두 아는 let 키워드는 아래와 같은 특징을 가지고 있습니다.
- let은 블록 스코프이므로 {블록} 범위 안에서만 사용 가능하다.
- let은 함수블록 안에 선언되어 있으면 함수블록 밖에서 호출하면 에러가 나온다.
- 변수는 재선언이 불가능하고 수정은 가능하다.
- 블록스코프이므로 영역이 겹치지 않으면 같은 이름을 사용할 수 있다.
#const
우리가 모두 아는 const 키워드는 아래와 같은 특징을 가지고 있습니다.
- const는 수정할수 없다.
- 객체의 속성은 수정할 수 없다.
- 객체를 수정(재선언)할 수 없지만 객체의 값은 수정할 수 있다.
#변수 생성 단계
자바스크립트는 3가지 단계를 거쳐 변수를 생성합니다.
- 선언 단계(Declaration Phase) : 변수 객체를 실행 컨텍스트에 등록한다.
- 초기화 단계(Initialization Phase): 등록된 변수의 메모리를 확보한다. 이 단계에서 변수는 undefined로 초기화된다.
- 할당 단계(Assignment Phase): 초기화된 변수에 실제 값을 할당한다.
let, const를 사용해 변수를 생성할 시에는 세 단계가 각각 따로따로 이루어지고,
var 을 사용해 변수를 생성할 시에는 선언 단계와 초기화 단계가 한번에 이루어지며,
함수 선언문 을 사용할 시에는 세 단계가 한 번에 이루어집니다.
#Temporary Dead Zone
아래 코드부터 보시겠습니다.
name = 'hello' // ReferenceError: Cannot access 'name' before initialization
let name = 'hi'
자. 만약 name이 호이스팅 되지 않았다면, 두 번째 let선언에서 already declared에러가 났었어야 합니다.
근데 현실은 초기화 하기전에 엑세스 할 수 없다는 에러를 내뱉었습니다.
또 아래 코드를 보시겠습니다.
function sayHello() {
return name
}
let name = 'hi'
console.log(sayHello()) // hi
별탈없이 hi를 내뱉은 것을 볼 수 있습니다. 그 말인 즉, name이 분명 호이스팅 되었다는 뜻이죠.
var는 선언과 동시에 초기화가 이루어집니다. 즉, 선언과 동시에 undefined가 할당됩니다.
그러나 let과 const는 다르죠. 선언만 될뿐, 초기화가 이루어지지 않습니다. 바로 이단계에서 TDZ에 들어가게 되는 것입니다.
즉, 선언은 되어있지만, 초기화가 되지 않아 이를 위한 자리가 메모리에 준비되어 있지 않은 상태라는 것이죵.
#호이스팅의 개념
함수 안에 있는 선언들을 모두 끌어올려서 해당 함수 유효 범위의 최상단에 선언하는 것을 말합니다.
예를 들어 아래 코드를 보시겠습니다.
var name = 'global name';
function callName() {
console.log(name); // ?
var name = 'local name';
};
callName();
위 예제 코드에서 출력되는 변수 name의 값은 'global name' 일 것 같지만, 'local name' 입니다.(지역함수가 최우선순위)
특정 스코프 안에서 선언된 변수(name)는 코드에 적힌 순서와 상관없이 "최상단에서 선언한 것처럼" 끌어올려진다.
이것을 호이스팅이라고 합니다.
#호이스팅을 사용할때 유의할 점
변수 선언과 함수 선언을 순서에 구애받지 않고 자유롭게 할 수 있다는 장점이 있지만 함수표현식과 같은 예외도 있기 때문에 신중히 사용해야만 합니다. 호이스팅만 믿고 중구난방으로 코드를 작성하기보다 처음부터 코드의 가독성과 유지보수를 고려해 개발하여 호이스팅이 발생하지 않도록 하는것이 최선이죠.
예를 들어 함수의 코드가 1000줄이고 950번째 라인에 변수를 선언한 코드를 분석한다고 가정해봅시다. 호이스팅에 의해 에러는 나지 않지만, 코드를 예측하기가 어렵다는 문제가 발생합니다.
편리하다는 이유로 가독성이 떨어지는 코드를 작성하지 않도록 주의합시다.
호이스팅이 발생하는것을 방지하기 위해서는 다음과 같은 조치방법이 있습니다.
- 변수와 함수를 가급적 유효범위의 상단부에서 선언한다
- 변수를 먼저 선언한 다음 함수를 선언한다
- var대신 let/const를 사용한다
'모르는용어 정리' 카테고리의 다른 글
얕은 복사와 깊은 복사 (1) | 2023.01.20 |
---|---|
undefined와 null (0) | 2023.01.20 |
기본형과 참조형 데이터 (0) | 2023.01.20 |
정적 타입과 동적타입 (0) | 2023.01.20 |
전역변수 (0) | 2023.01.20 |