var x = 10;
var x = 100;
console.log(x); // 100
var
로 선언한 변수는 중복 선언이 가능해서 위에 처럼 var
로 x 변수를 2번 선언해도 자바스크립트 엔진으로 인해 두번째 변수를 선언 할 때에는 var
가 없는 것처럼 동작해 오류라고 표시되지 않고 실행되는 부작용이 있다.
var a =20;
if(true){
var a = 100;
}
console.log(a); // 100
위와 같이 함수 밖에서 var
키워드로 선언한 변수는는 코드 블록 내에서 다시 선언해도 모두 전역 변수가 된다.
따라서 전역 변수를 남발할 가능성을 높이기 떄문에 의도치 않게 전역변수가 중복 선언되는 경우가 발생한다.
var
키워드로 변수를 선언하면 변수 호이스팅
에 의해 변수 선언문이 스코프의 선두로 끌어올려진 것처럼 동작한다.
console.log(a); // undefined
a = 2;
console.log(a); // 1
var a =1;
위의 코드에서 a
는 맨 아래에서 선언이 되었지만 변수 호이스팅에 의해 첫번째 줄인 console.log(a)
를 실행하기 이전에 a
가 선언되었다고 생각하고, 이 변수는 먼저 undefined
로 초기화 된다.
때문에 첫번째 줄에서 a
를 출력했을때 undefined
로 결과가 나온다.
그 후에 a=2
라고 값을 할당하면 그 이후에는 값이 할당이 되지만, 할당문 이전에 변수를 참조하면 언제나 undefined
를 반환한다.
그래서 var
키워드로 선언한 변수는 변수 선언문 이전에 사용 할 수 있고, 오류를 발생 시키지는 않지만
가독성을 떨어트리고, 오류를 발생시킬 여지를 남기기 때문에 지양하는 편이 좋다.
var
키워드의 단점을 보완하기 위해 등장한 let
는 var
키워드와 비교하며 보려 한다.
let x = 10;
let x = 100; // SyntaxError 발생
let
키워드는 중복 선언을 허용하지 않기 때문에 오류가 발생한다.
let a =20; // 전역변수
if(true){
let a = 100; // 지역변수
let b = 200;
}
console.log(a); // 20
console.log(b); // ReferenceError: b is not defined
let
키워드로 선언된 변수는 블록 레벨 스코프를 따르기 때문에 코드 블록 내에 선언된 a
,b
는 지역 변수이고, 블록 밖에 선언된 a
는 전역 변수다.
console.log(a); // ReferenceError, a is not defined
let a =1;
var
키워드로 선언한 변수는 자바스크립트 엔진에 의해 "선언 단계"와 "초기화 단계"가 한번에 진행지만
let
키워드로 선언한 변수는 "선언 단계"와 "초기화 단계"가 따로 진행된다.
let
키워드로 선언한 변수도 자바스크립트 엔진에 의해 런타임 이전에 변수가 "선언 단계"를 진행하지만, "초기화 단계"는 변수 선언문에 도달했을때 실행된다.
이렇게
let
으로 선언한 변수는 스코프의 시작 지점 ~ 초기화 시작 지점까지 변수를 참조할 수 없는데, 이 구간을 "일시적 사각지대" 라고 부른다
이러한 차이점 때문에 변수 호이스팅이 발생하지 않는 것처럼 보이지만 그렇지 않다.
자바스크립트 ES6에서 도입된 let
,const
를 포함해 모든 선언(function
, let
, const
, var
, function*
, class
등)을 호이스팅 한다. 다만 let
,const
,class
는 호이스팅이 발생하지 않는 것처럼 동작한다.
const
키워드는 상수를 선언하기 위해 사용한다. 하지만 반드시 상수만을 위해 사용하지는 않는다.
const
키워드는let
키워드와 특징이 대부분 동일하므로 let
키워드와 다른 점을 중심으로 살펴보려 한다.
const
로 선언한 변수는 반드시 "선언"과 동시에 "초기화"를 해야한다. 그렇지 않으면 SyntaxError
가 발생함.
const
키워드로 선언한 변수는 재할당이 금지된다.
상수는 재할당이 금지된 변수를 말한다. const
키워드로 선언된 변수에 원시 값을 할당한 경우 원시 값은 변경할 수 없는 값이고 const
키워드에 의해 재할당이 금지되므로 할당된 값을 변경할 수 있는 방법은 없다.
const
키워드로 선언된 변수에 객체를 할당한 경우 값을 변경할 수 있다.
const
키워드는 재할당을 금지할뿐 "불변"을 의미하지는 않는다.
const user = {
name: 'Gong'
};
user.name = "GongSuJeong"; // 객체는 변경 가능한 값이다. 따라서 재할당 없이 변경이 가능하다
console.log(user); // GongSuJeong
var
& let
& const
var
키워드 사용 자제let
키워드 이용 (이때, 변수의 스코프를 최대한 작게, 전역변수는 최대한 사용 자제)const
키워드 사용