let,const와 블록 레벨 스코프

정지훈·2020년 12월 1일
0

var 키워드로 선언한 변수는 중복 선언이 가능합니다.


var x = 1;
var y = 1;

var x = 100;

console.log(x); // 100

위 예제의 var키워드로 선언한 x변수는 재할당이 되어서 x는 100으로 재할당 되었다.

그리고 var로 선언한 변수는 오로지 함수의 코드 블록만을 지역 스코프로 인정합니다. 따라서 함수 외부에서 var키워드로 선언한 변수는 코드 블록 내에서 선언해도 모두 전역 변수가 됩니다.

var x = 1;

if(true) {
	var x = 10;
}

console.log(x) // 10;

그리고 var같은 경우 호이스팅이 이뤄나서 할당전에 참조를 하면 undefined로 초기화 된다.

console.log(x) // undefined
var x = 10;

이러한 var의 단점을 보완하기 위해 ES6에서는 새로운 변수 선언 키워드인 let과 const를 도입했습니다.

let은 같은 변수로 중복 선언 되면 문법 에러가 발생한다.

var foo = 123;
// var 키워드로 선언된 변수는 같은 스코프 내에서 중복 선언을 허용한다.
// 아래 변수 선언문은 자바스크립트 엔진에 의해 var 키워드가 없는 것처럼 동작한다.
var foo = 456;

let bar = 123;
// let이나 const 키워드로 선언된 변수는 같은 스코프 내에서 중복 선언을 허용하지 않는다.
let bar = 456; // SyntaxError: Identifier 'bar' has already been declared

let 과 const 는 블록 레벨 스코프가 생깁니다.

let과 const는 호이스팅이 이뤄지지 않은 것 처럼 보입니다.

console.log(foo); // ReferenceError: foo is not defined
let foo;

그 이유는 var같은 경우 런타임 이전에 선언과 초기화가 같이 이뤄나서 선언전에 참조를 하면 초기화 상태를 보여준다.

하지만 let 키워드는 선언과 초기화가 따로 이뤄난다. 그래서 초기화 전까지 일시적 사각지대에 들어서게 되는데 그래서 할당 전에 참조를 하면 일시적 사각지대에 있기 때문에 참조 에러가 발생한다.

그래서 호이스팅이 이루어지지 않은 것 처럼 보이는 것입니다.

하지만 이때 제가 왜 '이루어지지 않은 것 처럼 보이는 것' 이라고 설명하는 이유는 사실은 호이스팅이 이루어 지고 있다는 것 입니다.

let x = 10;

{
  console.log(x);
  let x = 30;
}

위 에처럼 let은 블록 레벨 스코프를 따른다 해서 x가 10이 나오길 기대하지만 스코프 안에서 let x가 선언이 되었고 초기화 전까지 일시적 사각지대 TDZ에 있기 때문에 참조에러가 발생한다.
그래서 let이나 const도 호이스팅이 있습니다.

전역 객체와 let

var 키워드로 선언한 전역 변수와 전역 함수는 전역 객체의 window의 프로퍼티가 된다 전역 객체의 프로퍼티를 참조할 때 window를 생략 가능하다.


var x = 1;

console.log(x); // 1
console.log(window.x) // 1

하지만 let과 const는 전역 객체로 들어가지 않고 전역 렉시컬 환경의 선언적 환경 레코드에 있습니다. 이것에 대해서는 실행 컨텍스트에서 살펴볼 내용이다.

const 키워드

const 키워드로 선언한 변수는 반드시 선언과 동시에 초기화해야 합니다.

그렇지 않으면 문법 에러가 발생합니다.

const noo = 1;
const foo; // SyntaxError: Missing initializer in const declaration

const키워드로 선언한 변수도 let 키워드로 선언한 변수와 마찬가지로 블록 레벨 스코프를 가지며 변수 호이스팅이 발생하지 않는 것 처럼 동작합니다.

let은 재할당이 가능하다(같은 변수로 재선언하는 건 불가능)
하지만 const는 재할당이 금지된다.

그래서 상수라는 개념이 있다.
상수는 재할당이 금지된 변수를 말하는 것이다. 하지만 const는 모든 것을 상수라고 하지 않는다.

const에 할당하는 값에 따라서 달라진다.
원시값을 할당할 경우 (원시값은 변경할 수 없는 값) 이것을 상수라고 하고 객체를 할당할 경우 변수라고 말한다.

객체는 재할당 없이도 직접 변경할 수 있기 때문이다.

따라서 const 키워드는 재할당을 금지할 뿐 불변을 의미하지 않는다.

let과 const vs var

나는 일단 const를 더 선호하고 let은 대도록 쓰지 않도록 하는 것을 더 선호한다.

만약 ES6을 사용한다면 var키워드는 사용하지 않고 재할당이 필요할 경우 let키워드를 사용하고 변경이 발생하지 않으면 const로 이용 하면 좋을 거 같다.

0개의 댓글