
변수 선언(declaration)이란?
ES6(ECMAScript 6) 이전에는 주로
var키워드를 사용하여 변수를 선언해 왔지만,var키워드의 단점을 보완하고자let,const키워드가 등장
스코프란?
: 식별자가 유효한 범위 or 식별자를 검색할 때 사용하는 규칙
var는 함수 단위 스코프(function-level-scope)를 가진다.
var 키워드로 선언된 변수는 함수 스코프를 가지며, 함수 내에 어디에서 선언되는 참조가 가능하지만, 외부로는 참조가 불가능하다.function foo() {
var a = 10;
console.log(a);
}
foo(); // 10
console.log(a); //ReferenceError: a is not defined
함수 단위 스코프를 가진다는 것은
var키워드의 대표적인 단점이기도 하다. 왜냐하면 이로 인해 의도치 않게 전역 변수가 선언되어 심각한 부작용이 발생할수도 있기 때문이다.
let과const는 블록 단위 스코프(block-level-scope)를 가진다.
function bar() {
let a = 10;
console.log(a) = 10;
}
console.log(a); // ReferenceError : a is not defined
let과 const로 선언된 변수는 블록 스코프를 가지며 블록 ({}) 내에서만 접근할 수 있다.변수 호이스팅이란?
: 변수 선언문이 코드의 선두로 끌어 올려진 것처럼 동작하는 자바스크립트 고유의 특징
var로 선언된 변수는 호이스팅이 발생한다.
console.log(a); // undefined : 변수 선언 이전에 참조 가능
var a // 초기화
console.log(a); // undefined
a = 10 // 값 할당
console.log(a); // 10
var로 선언된 변수는 선언 위치와 관계없이 함수 전역 또는 전역 스코프의 상단으로 끌어올려진다var로 선언된 변수는 런타임 이전 평가 단계에서 변수 선언 및 초기화가 동시에 이루어지기 때문에, 값을 할당하지 않더라도 undefined가 호출된다.
let,const로 선언된 변수는 호이스팅이 발생하지만, 다르게 동작한다.
console.log(a); // ReferenceError: Cannot access 'a' before initialization
let a; //
console.log(a); // undefined
a = 10;
console.log(a); // 10
let, const 키워드로 선언된 변수는 선언 이전에 접근할 수 없다.let, const 로 선언된 변수는 선언 단계와 초기화 단계가 분리되어 진행된다.TDZ(Temporal Dead Zone)가 존재하기 때문에, 호이스팅은 발생하지만 값을 참조할 수 없기 때문에 호이스팅이 발생하지 않는 것 처럼 동작한다.
var로 선언한 변수는 중복 선언 및 재할당이 가능하다.
var a = 10;
console.log(a) // 10
var a = 15;
console.log(a); // 15
var 키워드로 선언된 변수는 중복 선언 및 재할당이 가능하며 마지막에 할당된 값이 최종적으로 변수의 값으로 저장된다.
let으로 선언한 변수는 중복 선언은 불가하지만 재할당은 가능하다.
let a = 5;
let a = 10;
console.log(a); // SyntaxError: Identifier 'a' has already been declared
const로 선언한 변수는 중복 선언과 재할당 모두 불가하다.
const a = 5;
const a = 10;
cnosole.log(a); // SyntaxError: Identifier 'a' has already been declared
const도 let과 동일하게 중복 선언이 불가하다.const a = 5;
console.log(a); // 5
a = 10;
console.log(a); // TypeError: Assignment to constant variable.
const는 상수를 선언하는 키워드이기 때문에 재할당이 불가하다.const a = [1, 2, 3];
a[0] = 5;
console.log(a[0]); // 5
const person = {
name: "sean",
age: 20,
};
person.name = "Lee";
console.log(person.name); // Lee
※ 하지만, 변수의 값이 객체나 배열인 경우, 그 내부의 값은 변경할 수 있다.
