var greeter = "hey hi";
function newFunction() {
var hello = "hello";
}
console.log(greeter); // "hey hi"
console.log(hello); // error: hello is not defined
greeter
은 전역변수로 정의되어있고, hello
는 newFunction()
함수내에서 정의되어있다. 이때 log
띄워보면 greeter
은 전역변수여서 log가 나타나지만, hello
의 경우 함수내의 변수이기 때문에 함수 밖에서 불러냈을때 error가 발생한다.
var greeter = "hey hi";
var times = 4;
if (times > 3) {
var greeter = "say Hello instead";
}
console.log(greeter) // "say Hello instead"
time > 3
가 true
를 반환하기 때문에 greeter
는 "say Hello instead"
로 재정의된다. 의도적으로 재정의한 것이라면 괜찮겠지만, 변수 greeter
가 이미 정의되어 있다는 사실을 인식하지 못한 경우에는 문제가 된다.
만약 코드의 다른 부분에서 greeter
를 사용한 적이 있다면 변경된 사항을 모르고 다른 결과가 나옴에 의아해할 수 있다. 이러한 부분에서 많은 버그를 발생시킬 수 있기 때문에 let과 const가 필요하다.
var
선언에 대한 문제점 해결
let
으로 선언된 변수: 해당 블록 내에서만 사용가능let times = 4;
if (times > 3) {
let hello = "say Hello instead";
console.log(hello);// "say Hello instead"
}
console.log(hello) // hello is not defined
let
은 해당 범위 내에서 업데이트는 가능하지만, 재선언은 불가능하다. 아래의 코드로 살펴보면, greeting
변수를 두번 선언하면 해당 오류가 발생한다.
let greeting = "say Hi";
let greeting = "say Hello instead";
// error: Identifier 'greeting' has already been declared
하지만 동일 변수가 다른 범위 내에서 정의되면, 에러는 발생하지 않는다.
let greeting = "say Hi";
if (true) {
let greeting = "say Hello instead";
console.log(greeting); // "say Hello instead"
}
console.log(greeting); // "say Hi"
이는 say Hi
값이 저장된 변수greeting
과 say Hello instead
값이 저장된 변수greeting
가 서로 다른 범위에서 정의 되었기 때문에 아예 다른 변수라고 인식한다.
greeting
변수가 이와 같은 속성으로 이루어졌다고 보자.
const greeting = {
message: "say Hi",
times: 4
}
아래와 같이 속성 자체를 변경할 수는 없지만,
greeting = {
words: "Hello",
number: "five"
}
다음과 같이 속성의 값만을 바꾸는 것은 가능하다.
greeting.message = "say Hello instead";
var | let | const | |
---|---|---|---|
재선언 | O | X | X |
업데이트 | O | O | X |
특이사항 | - | - | 개체의 속성 업데이트 가능 |