Javascript

var와 let 그리고 const

M9M9 2020. 10. 15. 17:25

자바스크립트에서는 변수를 선언할 수 있는 방법이 3가지가 있다.

 

var와 let, 그리고 const가 있는데

 

let과 const는 es6문법에 추가된 변수 선언 방법이다.

 

그렇다면 기존에 var를 내버려두고 왜 추가되었는지 살펴보겠다.

 

 

 

var에 대한 문제점

 

1. hoisting

console.log(test);
test='테스트';
var test;


//console.log 결과값: undefined

var test를 맨 밑에 선언했는데 cosole.log(test) 결과는 undefined로 출력된다.

(※undefined란 변수가 선언됐지만 값이 할당되지 않았을 때 undefined가 할당된다).

 

또한, 

console.log(test);
test='테스트';
console.log(test);
var test;


//console.log 결과값: undefined , '테스트'

위의 코드에서 test에 '테스트' 문자열을 할당한 후, console.log(test)를 출력하는 코드를 넣었다.

그리고 출력하니 결과는 undefined랑, '테스트'가 출력되었다.

 

이처럼 변수를 선언하지도 않았는데 왜 이런 값이 나타는 것인가??

 

그 이유는 바로 var hoisting 문제 때문이다.

 

(※hoisting이란 어느 위치에 선언했는지 상관없이 항상 맨 위로 선언을 끌어올려주는 것이다.)

 

var로 선언 변수가 hoisting되기 때문에 코드에서 맨 위로 위치되기 된다. 그래서 변수는 선언됐지만, 값이 할당이 안된 undefined가 출력된다.

 

 

그래서 맨 처음 코드 1번 라인에 console.log(test)를 출력해도 undefined가 출력된다.

 

 

 

 

2. block scope

var는 함수에 해당하는 block scope 만이 존재하고, 그 외에는 block scope가 없다. 

 

무슨 말이냐면 

function testVar(){
    var value=7;
    console.log(value);   //result 7
}
testVar();
console.log(value);   // result: value is not defined

함수 내부에 선언된 var는 함수 외부에서 참조할 수 없다. 모든 개발 언어에서 이와 동일하기 때문에 당연하다 생각이 든다. 

 

하지만,

function testVar(){
    var value=7;
    console.log(value); //7

    if(true){
        var valueTwo=10;
    }
    console.log(valueTwo); //10
}
testVar();

if 내부에서 선언한 변수를 외부에서 참조할 수 있다.

다른 개발언어는 변수가 if와 for문의 블록 스코프가 있기 때문에 이런 일이 발생하지 않는다.

 

즉, 함수 블록 스코프 이외에는 다른 블록 스코프를 갖고 있지 않다.

이로 인해, 프로그래밍 도중 문제가 발생할 수 있다.

 

 

 

 

 

 

var의 문제점을 해결할 수 있는 새로운 변수 선언방법 'let'

let을 사용하면 var의 hoisting문제와 block scope문제를 모두 해결할 수 있다.

 

1. hoisting 해결

 

위의 코드에서

console.log(test);
test='테스트';
let test;


//console.log 결과값: Cannot access 'test' before initialization

var 형식으로 let을 선언하면 선언전에 test 변수에 접근할 수 없다고 에러가 뜬다.

 

 

그래서 먼저 let은 변수를 선언 후 진행해야한다.

let test;
test='테스트';
console.log(test);

//console.log 결과값: '테스트'

 

 

 

2. block scope 해결

 

function testVar(){
    var value=7;
    console.log(value); //7

    if(true){
        let valueTwo=10;
    }
    console.log(valueTwo); //valueTwo is not defined
}
testVar(); 

위의 코드의 valueTwo의 변수를 var에서 let방법으로 바꿨다.

 

let은 함수 스코프뿐만 아니라 if, for, 개인 block scope를 갖고 있기 때문에 외부에서 참조할 수 없다.

 

 그래서 위의 코드에서 if문 내부에 선언한 valueTwo 변수는 if문 외부에서 참조할 수 없다.

 

 

 

let의 특징

let은 변수를 선언과 할당을 같이 하던가, 선언 후에 할당을 따로 해도된다.

let val1;
val1=3;

let val2=4;
val2=6;

코드와 같이 가능하다. 

또한, 기존의 val2의 값을 6으로도 변경시킬 수 있다.

 

 

그 이유는 let으로 선언한 변수는 메모리에서 값을 읽고 쓰기가 가능하기 때문이다.

 

 

 

 

const 변수

const 변수는 다른 개발언어와 마찬가지로 '상수'이다.

 

(※상수: 변하지 않는 수)

그래서 const라고 선언한 변수는 값을 바꾸지 못한다.

const test=5;
test=4;
console.log(test);//result: Assignment to constant variable

값을 변경하면 오류가 뜨는 것을 볼 수 있다.

오류가 뜨는 이유는 const로 생성한 변수는 메모리에서 읽기만 가능하기 때문이다.

const로 선언한 변수를 선언과 할당을 동시에 한 다음에는 변경할 수 없게 잠긴다고 생각하면된다. 그래서 읽기만 가능하다. 

 

또한, 선언과 동시에 값을 할당해야 한다.

const test;
test =3;
console.log(test); //result: Missing initializer in const declaration

이렇게 선언과 할당을 따로 하면 에러가 생기므로, 

const test=3; 이런 식으로 선언과 할당을 한 번에 해야 한다.

 

 

 

 

 

그렇다면 const를 왜 사용할까

 

1. 보안상의 이유: 만약, let으로 작성했다면 헤커들이 변수의 값을 임의로 바꿔 값을 계속 변경해나가며 프로그램에 영향을 줄 수 있다. 하지만 const로 바꾸면 값을 변경하지 못한다.

 

2. thread safey: 프로그램이 실행되면 하나의 프로세스가 할당되는데, 이때 프로세스 내에 다양한 스레드가 동시에 돌아가며 프로그램을 더욱 효율적이고 빠르게 동작시켜준다. 그런데 스레드들이 동시에 한 변수에 접근했을 때, 값을 여러 값으로 변경하게 되면 위험하다. 그래서 const로 지정해놓으면 그런 일을 사전에 방지할 수 있다.

 

3. 개발자의 실수: 개발하다 보면 자신도 모르게 그 값을 변경할 수 있다. 그래서 값이 변하지 않아야 할 값이라면 const로 변수를 설정해서 실수를 방지하기 위해 사용한다.

 

 

 

 

 

 

참고:  www.youtube.com/watch?v=OCCpGh4ujb8&list=PLv2d7VI9OotTVOL4QmPfvJWPJvkmv6h-2&index=3