JavaScript 변수 선언 방식에는 const, let, var 이렇게 3가지가 존재한다.
3가지 선언 방식의 차이점을 알기 위해서 선행되어야 할 스코프(Scope) / 호이스팅(Hosting) 을 알아야하기에 하나씩 짚고 넘어가자
1. 스코프(Scope)
스코프란 우리말로 직역하자면 "범위"라는 뜻인데 JavaScript에서는 "변수가 선언될 당시 접근 가능한 범위" 라는 의미로 사용된다, 예시를 하나 들어보자
function first(){
second();
console.log(a);
}
function second(){
let a = "This is test Data";
console.log(a);
}
first();
해당 코드를 실행하면 second 함수에서는 a의 값이 정상적으로 찍혀 "This is test Data" 라는 문자가 콘솔로그에 찍히게 될 것이다, 하지만 first 에서 a라는 변수에 접근하려고 하면 a is not defined 라며 에러를 뱉을 것이다, 왜냐하면 a라는 변수가 선언될 당시에 접근 가능한 범위는 second 함수 내부에서만 가능한 것이다, first 에서는 a라는 변수에 접근 권한이 없기 때문에 first 에서 a에 접근 하려고 하면 에러가 나는 것이다.
이렇듯 변수가 접근 가능한 범위를 우리는 스코프라고 말한다.
2.호이스팅
function func() {
console.log(a);
var a = "test data";
}
func();
위 코드를 보면 a 변수는 콘솔로그에 a를 찍은 이후에 선언이 되었다 자 그렇다면 과연 위 코드를 실행한다면 콘솔 로그에 과연 에러가 떨어질까???
실제로 저 코드를 실행시키면 콘솔로그에는 undefined 라는 값이 찍힐 것이다, 왜냐하면 자바스크립트 엔진은 실행 컨텍스트를 위한 과정에서 모든 선언을 해당 스코프에 등록 시킨 후 코드를 실행하기 때문이다.
function func() {
var a;
console.log(a);
a = "test data";
}
이런 식으로 코드가 변경되는 것처럼 보이는데,그렇기 때문에 a를 콘솔로그 찍었을 때 undefined 값이 찍히게 되는데 실제로 최상단에 끌어올려지는 것은 아니고 끌어올려지는 것 처럼 보이는 현상을 호이스팅이라고 한다.
1.const
function func(){
const pi = 3.141592;
//재선언 불가능
const pi = 3.14;
//재할당 불가능
pi = 3;
}
const 의 경우 한번 선언을 해놓으면 재선언 및 재할당이 불가능하다,
위와 같은 코드가 있다고 가정한다면 const pi = 3.141592;로 최초에 선언을 하였기에 동일한 변수명으로 재선언한 const pi = 3.14; 코드에서 에러가 날 것이다, 또한 pi =3; 으로 재할당 한 부분 또한 에러로 처리되어 코드상 문제가 생길 것이다 그렇기 때문에 const 로 선언하는 경우에는 값이 변하지 않을 경우에만 사용하여야 한다, 하지만 여기서 주의해야 할 점이 있다
function func(){
const person = {
name : "홍길동"
};
person.name = "아무개";
}
위와 같이 Object 형식으로 선언을 했을 경우에는 값에 대한 재할당이 가능하기 때문에 Object 형식으로 선언 시 주의가 필요하다. (엄밀히 말하자면 값에 대한 재할당은 아니다, 오브젝트의 주소값을 선언한 것이기 때문에 주소값이 변하지 않는다면 에러가 나지 않는다 다만, 편의상 재할당이 가능하다고 하겠다) 그리고const 의 경우 선언과 할당이 동시에 이루어져야한다, 선언만 이루어질 경우 또한 문법 에러가 떨어진다.
2. let
function func() {
let a = "test data";
//재할당 가능
a = "This is test data";
//재선언 불가능
let a = "again";
if(true){
//블록 스코프이기 때문에 해당 스코프에서는 재선언 가능
let a = "test";
console.log(a);
}
}
let 의 경우는 대부분 const 와 동일하지만 다른점은 재할당이 가능하다는 점이다.
또한 var와 let,const 가 다른 점은 var 의 경우 함수 레벨 스코프를 따르지만 let과 const의 경우 블록 스코프를 따른다, 그렇기 때문에 최초 let a = "test data"; 라고 선언을 하였고 원래대로라면 let 은 재선언이 불가능하기에 let a ="test" 라는 코드는 에러가 나야하지만 if(true) 문에서 새로운 블록 스코프가 생성되었기 때문에 let a= "test"; 로 선언이 가능해진다.
또한 let과 const 는 var 와는 다르게 호이스팅이 이루어지지 않는 것처럼 보이는데 그 이유는 다음과 같다.(실제로는 호이스팅이 이루어짐)
아래는 실제 변수가 선언될 당시 이루어지는 방식을 단계별로 세분화해놓은 것이다.
1. 선언 단계 - 실행 컨텍스트에 존재하는 변수 객체에 변수를 등록한다.
2. 초기화 단계 - 변수 객체의 메모리 공간을 확보하고 암묵적으로 undefined 값을 할당한다.
3. 할당 단계 - 초기화된 undefined를 대체할 실제 값을 할당한다.
var 의 경우 선언단계와 초기화 단계가 동시에 진행되고 let 과 const의 경우 선언 단계와 초기화 단계가 나뉘어져 있다.
그렇기 때문에 var 의 경우 호이스팅이 이루어질 때 이미 undefined로 값이 초기화 되어 문법 에러가 나질 않는데 ,let 과 const의 경우 호이스팅이 이루어지는 시점이 선언 이후 초기화 단계를 거치기 전에 이루어지기 때문에 변수에 액세스할 수 없어 문법 에러가 떨어지는 것이다.
3.var
function func(){
var a = "test";
//재선언 가능
var a = "test data";
// 재할당 가능
a = "This is test data";
}
var 의 경우 let 과 const 와는 다르게 재선언,재할당이 전부 가능하다,
그렇기 때문에 코드를 유지보수 하다보면 다른 사람이 이미 선언해놓은 변수인지 모르고 재선언을 해서 코드가 엉망이 되는 경우가 생긴다, 따라서 기왕이면 let 과 const 를 사용해서 이러한 문제를 미연에 방지하기를 추천한다.
'front > JavaScript' 카테고리의 다른 글
이벤트 루프(Event Loop) (0) | 2022.07.22 |
---|