프론트엔드/Tips

자바스크립트 변수 선언 - var, let, const

Marshall K 2019. 5. 23. 02:24

저도 사실 처음 자바스크립트를 배울 때 좀 오래된 강좌를 보고 시작해서 변수를 var로 선언하는 습관이 있었는데, var로 변수를 선언하는 건 좋은 방법이 아닙니다.


요점만 간단히 설명하고 가자면, 기본적으로 const로 변수를 지정하고, 아래에서 변수의 내용이 바뀐다면 let을 사용하시면 됩니다.


대부분의 프로그래밍 언어는 block-level (블록 레벨) 스코프를 따릅니다.

자바스크립트의 var은 예외로 funciton-level (함수 레벨) 스코프를 따릅니다.


무슨 소리냐 하면


function-level scope

- 함수 내에서 지정된 변수는 함수 내부에서 유효하며, 외부에선 참조할 수 없습니다.


block-level scope

- 코드 블럭 (함수, for, while, if 등 "{" 와 "}" 사이) 내에서 지정된 변수는 코드 블럭 내부에서 유효합니다.



간단한 예제로 설명해보겠습니다.


(function () {
for (var i = 0; i < 10; i++) {
console.log(i)
}
console.log(i)
})()


이 코드의 실행 결과는



위와 같이 나옵니다. for 안에서 변수를 선언했는데, for 문 밖에서도 i에 접근할 수 있습니다.

또한, for 안에서 i는 9까지만 증가했는데, 10이라는 이상한 값을 출력합니다.


(function () {
for (let i = 0; i < 10; i++) {
console.log(i)
}
console.log(i)
})()


위 코드를 실행하면



for 밖에서 i는 선언되지 않았으니, i가 선언되지 않았단 오류를 돌려줍니다.




또 다른 문제는, 변수는 선언 -> 초기화 -> 할당이란 단계를 거치며 지정이 되는데, var은 선언과 초기화가 동시에 이뤄진단 겁니다.


console.log(test) //undefined

var test
console.log(test) //undefined

test = 1
console.log(test) //1


var을 사용하면 test를 선언하기도 전에 console.log를 시켰지만, 아무런 에러를 반환하지 않습니다.


console.log(test)

let test
console.log(test)

test = 1
console.log(test)
//Uncaught ReferenceError: Cannot access 'test' before initialization


let을 사용하면 항목을 초기화하기 전에 접근했다고 에러를 반환합니다.


test = 1
var test

console.log(test)


이러면 1이라는 값을 반환해주는 환장할 상황도 발생합니다.




또한, var로 변수를 지정하게 되면, 아래에서 똑같은 이름으로 다시 지정하건 변수 선언 전에 변수 내용을 지정하건 오류가 발생하지 않습니다.

"오류만 없으면 만사 ok"라 하고 넘어가기도 힘든 게, 이렇게 하다 뭐가 꼬이게 되면 해답을 찾기가 굉장히 어려울 겁니다.


var a = "hello"
var a = "world"


이러면 a는 world가 됩니다.


const a = "hello"
const a = "world"
//Uncaught SyntaxError: Identifier 'a' has already been declared


const와 let은 변수를 재선언할 수 없습니다.




const와 let의 차이는 재할당 가능 여부입니다.


const a = "hello"
a = "world"
//Uncaught TypeError: Assignment to constant variable.

let a = "hello"
a = "world"


let은 변수의 내용을 변경할 수 있지만, const는 내부 내용을 변경할 수 없습니다.


const a //Uncaught SyntaxError: Missing initializer in const declaration


내용을 변경할 수 없으니 const로 변수를 지정할 땐 반드시 변수가 의미하는 바가 무엇인지 할당해줘야 합니다.



그래서 글 초반에 기본적으로 const를 사용하되, 변수의 내용이 변한다면 let을 사용하라 적은 것입니다.



const twice = {rapper: "chaeyoung"}

twice.rapper = "dahyun"

console.log(twice.rapper) // "dahyun"


주의하셔야 할 것은, const로 Object(객체)를 할당해도 객체의 내용은 변경 가능하단 것입니다.




강조를 위해 한 번 더 정리하자면


(function () {
for (let i = 0; i < 10; i++) {
console.log(i)
}
})()

(function() {
let tmp
1 === 1
? tmp = true
: tmp = false
})


기본적으로 변수를 const로 선언하고, 위 상황처럼 '변수의 내용이 변경된다' 하면 let으로 선언하시면 됩니다.