moon palace

[Java Script] var, let, const 의 차이점 본문

JavaScript

[Java Script] var, let, const 의 차이점

Hdaleee 2020. 2. 19. 20:43

Java Script에서는 세 가지 방법으로 변수를 선언할 수 있다.
제목에서와 같이 var / let / const 로 선언을 할 수 있는데,
굳이 변수를 선언하는 종류가 세가지씩이나 필요한 이유는 무엇일까?

짐작하기로는 당연히 각자 다른 역할이 있으니 구분을 하는 것이겠지만,
막상 공부를 이제 막 시작하는 입장에서는 조금 혼란스러울 수밖에 없다.
조금 있어보이는 단어로 말하자면 '재선언'과 '재할당', 'Scope'의 차이로 말할 수 있는데
이렇게만 말하면 너무 막연하니 하나씩 설명해보도록 하겠다.

바쁘거나 요약이 필요한 분들이라면 스크롤을 잽싸게 내리자!
맨 아래에 요약이 있다. 하지만 요약만 보고 넘어가는 것을 권장하지는 않는다.


1. 재선언
재선언은 말 그대로 선언을 다시 한다는 것을 의미한다. 한번 선언했던 변수를 다시금 선언하는 경우가 있는데 그럴 때에 종류에 맞는 선언을 사용해야 한다. 아래 예시를 보면 var를 제외한 let과 const는 재선언이 안된다는 것을 알 수 있다.

// var의 재선언
var testVar = 'varA'
var testVar = 'varB'

console.log(testVar) 
// "varB"


// let의 재선언
let testLet = 'letA'
let testLet = 'letB'
// SyntaxError 발생

console.log(testLet)
// "letA"


// const의 재선언
const testConst = 'constA'
const testConst = 'constB'
// SyntaxError 발생

console.log(testConst)
// "constA"

2. 재할당
재할당도 재선언과 같이 변수에 값을 다시 할당한다는 뜻이다. 재선언과 헷갈릴 수도 있는 부분인데 자세히 생각해보면 큰 차이가 있는 개념이다. 다음을 보면서 위의 재선언과 비교해보자. var와 const는 크게 차이가 없지만 let의 경우 재선언은 안되지만 재할당은 가능하다는 점을 알 수 있다.

// var의 재할당
var testVar = 'varA'
testVar = 'varB'

console.log(testVar) 
// "varB"


// let의 재할당
let testLet = 'letA'
testLet = 'letB'

console.log(testLet)
// "letB"


// const의 재할당
const testConst = 'constA'
testConst = 'constB'
// SyntaxError 발생

console.log(testConst)
// "constA"

아직 실무 필드에서 작업을 해보지 않았음에도 불구하고 공부를 하다 보면 비슷한 단어를 변수로 사용하는 경우가 있다. 특히 필자의 경우에는 result 라는 단어을 변수로 자주 사용하는데, var 만을 가지고 선언을 하면 변수의 값이 습관적인 이유로 중복 사용되어 재선언 오류가 나는 경우가 있다. 그래서 필자는 let을 주로 사용하고 있다. 재선언이 된다고하면 공부를 시작하는 입장에서는 어딘가 더 기능이 많다고 느껴질 수 있는데 오히려 중복 안전장치가 없다고 생각하면 이해가 빠를 것 같다.
다시 재할당 이야기로 돌아와서 재할당은 언제 사용할까? 공부를 하다보면 곧 '반복문'과 '조건문'을 마주하게 될 텐데 보통의 경우에는 그때가 재할당을 가장 먼저 마주하게 되는 순간이 아닐까 싶다. 예를 들어 비어있는 문자열을 변수로 지정해 두고, 특정한 조건이 충족되었을 때 그 변수의 문자열 뒤에 어떠한 메시지를 추가해서 값을 출력해야 한다고 할 때, 아래와 같이 재할당을 사용할 수 있다.

let result = 'hello, ';
let name = 'hdaleee';
function myName(){
    result = result + name;
    return result;
}
myName()
// "hello, hdaleee"

4번째 줄에서 'hello, '로 선언되어 있는 result 값에 name의 값을 한 뒤 재할당 한 모습을 볼 수 있다. 이 경우 다른 곳에서 name의 값을 다시 재할당한다면 결과는 바뀐 이름으로 출력될 것이다.


3. Scope / 스코프
마지막 구분점은 스코프이다. 스코프는 유효 범위라고 생각할 수 있다. 달리 말해서 선언된 값이 영향력을 갖는 범위를 지칭한다. 오늘 살펴볼 스코프는 총 세 개인데 하나는 function level scope(), 또 하나는 block level scope, 마지막은 global scope이다. 이름에서도 대략적으로 짐작할 수 있듯이 function scope는 선언된 함수 범위를 지칭한다. 반면 block scope는 중괄호({})로 구분된 범위를 지칭하며, global scope는 모든 영역에 영향력을 미친다. 아래 예시를 보면 이해가 쉬울 듯하다.

3_1. Function Scope 
function scope 내에서 선언된 변수는 외부에서 호출 시 정의되지 않은 변수라고 에러가 뜬다.

// function scope_ 함수 내에서 호출
function sayHello () {
  var helloVar = 'hello, var';
  let helloLet = 'hello, let';
  const helloConst = 'hello, const';

  console.log(helloVar)
  console.log(helloLet)
  console.log(helloConst)
}
sayHello()
// hello, var
// hello, let
// hello, const

// function scope_ 함수 밖에서 호출
function sayHello () {
  var helloVar = 'hello, var';
  let helloLet = 'hello, let';
  const helloConst = 'hello, const';
}
console.log(helloVar)
// ReferenceError
console.log(helloLet)
// ReferenceError
console.log(helloConst)
// ReferenceError

3_2. Block Scope 
function scope와 동일한 개념으로 중괄호 내에서 선언된 변수는 외부에서 호출 시 정의되지 않은 변수라고 에러가 뜬다.

// block scope_ block 내에서 호출
{
  var helloVar = 'hello, var';
  let helloLet = 'hello, let';
  const helloConst = 'hello, const';

  console.log(helloVar)
  console.log(helloLet)
  console.log(helloConst)
}
// hello, var
// hello, let
// hello, const

// block scope_ blcok 밖에서 호출
{
  var helloVar = 'hello, var';
  let helloLet = 'hello, let';
  const helloConst = 'hello, const';
}
console.log(helloVar)
// ReferenceError
console.log(helloLet)
// ReferenceError
console.log(helloConst)
// ReferenceError

3_3. Global Scope / 전역 스코프
global scope는 어렵지 않다. 모든 영역에 영향력을 가진다. 전역 스코프에 선언된 변수를 전역 변수라고 하며 실질적으로 전역 스코프라는 말보다 전역 변수라는 말을 더 많이 사용하는 듯하다.

// global scope

var helloVar = 'hello, var';
let helloLet = 'hello, let';
const helloConst = 'hello, const';

// global scope_ blcok에서 호출
{
  console.log(helloVar)
  console.log(helloLet)
  console.log(helloConst)
}
// hello, var
// hello, let
// hello, const

// global scope_ function에서 호출
function sayHello () {
  console.log(helloVar)
  console.log(helloLet)
  console.log(helloConst)
}
sayHello()
// hello, var
// hello, let
// hello, const

3_4. 그렇다면 var / let / const의 차이는?
결론부터 이야기하자면, var는 function scope이고 let과 const는 block scope이다. function scope는 함수 밖에서 선언되면 무조건 global scope로 인식이 되기에 과도한 전역 변수를 생성할 우려가 있다. 아래 예시로 차이점을 확인할 수 있다. 

var name = 'hdaleee';
// 전역 변수로 선언 됨

console.log(name); 
// "hdaleee"

{
  var name = 'vanillasky'; 
  // 함수 내에 있지 않기에 block 내에 있어도 전역 변수로서 재선언 됨
}

console.log(name); 
// "vanillasky"
// 전역 스코프에서 호출 시 재선언된 값으로 나온다.

 

오늘의 내용을 요약하자면 아래 표와 같이 정리할 수 있다.

구분 var let const
재선언 가능 불가 불가
재할당 가능 가능 불가
스코프 function level scope block level scope block level scope
예제

var testCase = ‘var’
// output: var
var testCase = ‘var2'
// output: var2
var = ‘var3'
// output: var3

let testCase = 'let'
// output: let
let testCase = 'let2'
// output: error
testCase = 'let3'
// output: let3

const testCase = 'const'
// output: const
const testCase = 'const2'
// output: error
testCase = 'const3'
// output: error

최대한 가볍게 한 문장으로 요약하자면
"var의 문제점을 보완한 것이 let이고, let보다 조금 더 엄격하게 사용하고 싶다면 const를 사용하면 된다." 정도로 볼 수 있을 것 같다.

Comments