[모던 자바스크립트 Deep Dive] 15. let, const 키워드와 블록 레벨 스코프
🎉 let, const 키워드와 블록 레벨 스코프
😉 var 키워드로 선언한 변수의 문제점
🐱🐉 변수 중복 선언 허용
선언한 변수에 같은 스코프 내에서 중복 선언이 허용되어 변수값이 변화된다.
var x = 1;
var y = 1;
//var 키워드로 선언된 변수는 같은 스코프 내에서 중복 선언을 허용한다.
//초기화문이 있는 변수 선언문은 자바스크립트 엔진에 의해 var키워드가 없는 것 처럼 동작한다.
var x = 100; //이 곳에서 x에 100이 재할당됨
//초기화문이 없는 변수 선언문은 무시된다.
var y;
console.log(x); //100
console.lgo(y); //1
동일한 이름의 변수가 이미 선언되어 있는 것을 모르고 변수를 중복 선언하면서 값까지 할당했다면 의도치 않게 먼저 선언된 변수 값이 변경되는 부작용이 발생한다.
🐱🐉 함수 레벨 스코프
var키워드는 오로지 함수의 코드 블록만을 지역 스코프로 인정해 if문, for문과 같은 블록 스코프로 이루어진 문에서는 전역 변수로 작용해 의도치 않게 중복 선언되는 일이 발생한다.
var x = 1;
if (true) {
//x는 전역 변수이다.
//이미 선언된 전역 변수 x가 있으므로 x 변수느느 중복 선언된다.
//이는 의도치 않게 변수값이 변경되는 부작용이 발생한다.
var x = 10; //x값이 변경되었다.
}
console.log(x); //10
🐱🐉 변수 호이스팅
변수 호이스팅에 의해 var키워드로 선언한 변수는 변수 선언문 이전에 참조할 수 있게 된다.
- 변수 선언 전의 값은 undefined이다.
- 프로그램 흐름과 맞지 않고 가독성을 떨어뜨려 오류를 발생시킬 여지가 많다.
//이 시점에서 변수 호이스팅에 의해 이미 foo변수가 선언되었다.(1.선언단계)
//변수 foo는 undefined로 초기화된다.(2.초기화 단계)
console.log(foo); //undefined
//변수에 값을 할당(3.할당 단계)
foo = 123;
console.log(foo); //123
//변수 선언은 런타임 이전에 자바스크립트 엔제에 의해 암묵적으로 실행된다.
var foo;
위 예제는 변수 선언문이 가장 코드의 아래에 있음에도 선언문 위의 호출 명령과 할당이 가능한 것을 볼 수 있다. 이를 변수 호이스팅에 의해 나타난 결과이다.
😉 let 키워드
🐱🐉 변수 중복 선언 금지
let키워드로 이름이 같은 변수를 선언하면 문법에러(SyntaxError)가 발생한다.
🐱🐉 블록 레벨 스코프
블록 레벨 스코프 : 모든 코드 블록(함수, if문, for문, while문, try/catch 문등)을 지역 스코프로 인정한다.
let foo = 1; //전역 변수
{
let foo = 2; //지역 변수
let bar = 3; //지역 변수
}
console.log(foo); //1
console.log(bar); //ReferneceError : bar is not defined
함수도 코드 블록이므로 스코프를 만든다. 이때 함수 내의 코드블록은 함수 레벨 스코프에 중첩된다.
let i = 10;
function foo(){ --------------------------
let i = 100; | 함수 레벨 스코프
fot(let i = 1; i<3; i++){ ---- |
console.log(i); /*1 2*/ |블록 |
} |레벨 |
console.log(i); /*100*/ ---- 스코프 |
} --------------------------
foo();
console.log(i); //10
🐱🐉 변수 호이스팅
let 키워드로 선언한 변수는 ‘선언단계’와 ‘초기단계’가 분리되어 진행된다.
- 런타임 이전에 자바스크립트 엔진에 의해 암묵적으로 선언 단계가 실행되지만 초기화 단계는 변수 선언문에 도달할때 실행된다
console.log(foo); //ReferenceError : foo is not defined
let foo;
그래서 초기화 단계가 실행되기 이전에 변수에 접근하려고 하면 참조 에러가 발생한다.
즉, let
키워드는 선언한 변수는 변수 호이스팅이 발생하지 않는 것 처럼 동작한다.
일시적 사각지대 : let
키워드로 선언한 변수는 스코프의 시작 지점부터 초기화 단계시작 지점(변수 선언문)까지 변수를 참조 할 수 없는 구간.
🐱🐉 전역 객체와 let
let
키워드로 선언한 전역 변수는 전역 객체 프로퍼티가 아님으로 window.식별자방식으로 접근 할 수 없다.
let
전역 변수는 보이지 않는 개념적인 블록(전역 렉시컬 환경의 선언전 환경 레코드)내에 존재하게 된다.
😉 const 키워드
🐱🐉 선언과 초기화
const키워드로 선언한 변수는 반드시 선언과 동시에 초기화해야 한다. -> 그렇지 않으면 문법적 오류 발생
- let과 동일하게 블록레벨스코프르 가지며 변수 호이스팅이 일어나지 않는것 처럼 보인다.
{
//변수 호이스팅이 발생하지 않는 것처럼 보인다.
console.log(foo); //ReferenceError: Cannot access 'foo' before initialization
const foo = 1;
console.log(foo); //1
}
//블록 레벨 스코프를 갖는다.
console.log(foo); //ReferenceError: foo is not defined.
🐱🐉 재할당 금지
const 키워드로 선언한 변수는 재할당이 금지된다.
const foo = 1;
foo = 2; //TypeError : Assignment to constant variable.
🐱🐉 상수
상수는 재할당이 금지된 변수
const 키워드는 상수를 표현하는데 사용한다.
- 상수는 상태 유지와 가독성, 유지보수의 편의를 위해 적극적으로 사용해야 한다.
- const 키워드로 선언된 변수에 원시 값을 할당한 경우 원시 값은 변경할 수 없는 값이고 const 키워드에 의해 재할당이 금지되므로 할당된 값을 변경할 수 있는 방법은 없다.
- 대문자로 선언해 상수임을 명확히 나타낸다.
- 여러 단어인 경우, 언더스코어(_)로 구분해 스네이크 케이스로 표현한다.
//세율을 의미하는 0.1은 변경할 수 없는 상수로서 사용될 값이다.
//변수 이름을 대문자로 선언해 상수임을 명확히 나타낸다.
const TAX_RATE = 0.1;
//세전 가격
let preTaxPrice = 100;
//세후 가격
let afterTaxPrice = preTaxPrice + preTaxPrice * TAX_RATE;
console.log(afterTaxPrice); //110
🐱🐉 const키워드와 객체
const 키워드로 선언된 변수에 객체를 할당한 경우 값을 변경 할 수 있다.
const person = {
name: "Lee",
};
//객체는 변경 가능한 값이다. 따라서 재할당 없이 변경이 가능하다.
person.name = "Kim";
console.log(person); //{name : "Kim"}
- 새로운 값을 재할당하는 것은 불가능하지만, 프로퍼티 동적 생성, 삭제, 프로퍼티 값의 변경을 통해 객체를 변경하는 것은 가능하다.
😉 var vs let vs const
- 변수 선언할때에는 기본적으로 const를 사용하며
-
let은 재할당이 필요한 경우에 한정적으로 사용
- ES6를 사용한다면 var는 사용하지 않는다.
- 재할당이 필요한 경우에 한정해서let키워드를 사용한다. 이때 변수의 스코프는 최대한 좁게 만든다.
- 변경이 발생하지 않고 읽기 전용으로 사용하는 (재할당이 필요없는 상수) 원시값과 객체에는 const키워드를 사용한다.
const
키워드는 재할당을 금지하므로var
let
키워드보다 안전하다
Leave a comment