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 |
| 특이사항 | - | - | 개체의 속성 업데이트 가능 |