[ES6] - let/const

let 키워드 사용 : 블록 스코프 변수 생성

자바스크립트 기본적으로 함수 단위의 스코프를 제공하고 있는데, 다른 언어들과는 다른 부분이기 때문에 이러한 특징을 잘 알고 있지 않으면 코드 작성에 어려움을 겪거나 메모리 누수를 낳는 코드를 만들 가능성이 높다.
ES6에서는 이러한 다른 언어들의 특성을 받아들여 블록 단위의 변수 선언을 할 수 있는 let 키워드가 추가가 되었다.
기존 컴파일 언어나 다른 언어를 쓰던 개발자들도 이제 쉽게 블록 단위의 변수 선언을 통하여 햇갈리지 않는 개발이 가능하다.

var 키워드가 표준에서 빠지는 건 아니기 때문에, 새로 추가된 let 키워드의 스코프 특성에 대해 잘 알고 있어야 한다.

1
2
3
4
5
6
7
var a = 1;
console.log(a);
function printNumberZ(){
console.log(a);
var a = 2;
}
printNumber();
1
2
3
[출력결과]
1
2

위와 같은 코드가 있다고 할때, 출력 결과를 생각해보면 자바스크립트 변수 특징에 대해 원래 잘 알고 있는 개발자라면 쉽게 대답할 수 있는 결과가 출력이 될 것이다.
기본 var 변수로 선언하면 함수 단위의 스코프로 생성되기 때문에, 자신의 스코프에 있는 함수를 먼저 참조하게 된다. 그래서 출력 결과가 같은 스코프에 있는 변수를 바라보게 되는 것이다.

let 키워드를 사용한 샘플 코드를 작성해봤는데 간단하게 결과를 예측해봐도 재밌을꺼 같다.

1
2
3
4
5
6
7
8
let a = 10;
console.log(a);
function printLetVariable(){
let a = 20;
console.log(a);
}
printLetVariable();
console.log(a);
1
2
3
4
[출력결과]
10
20
10

출력 결과를 살펴보니, let도 역시 같은 스코프에 있는 변수를 참고 하는 것을 기본으로 하고 있다.
그렇다면 코드를 살짝 틀어서 중복으로 선언했을 경우를 생각해보자. 먼저 var 변수 선언의 경우를 보고 그 다음에 let 변수 선언에 대해 테스트 코드를 작성해보자.

1
2
3
var a = 10;
var a = 20;
console.log(a);
1
2
[출력결과]
20
1
2
3
let a = 10;
let a = 20;
console.log(a);
1
2
[출력결과]
SyntaxError: Identifier 'a' has already been declared

Node.js 6.x 버젼에서 테스트를 해봤는데 위와 같은 결과가 리턴되었다. 변수 특성에 대한 결과를 정리해보자.

  • let 변수는 같은 스코프에 있을 경우 중복으로 선언하면 TypeError 예외를 발생시킨다.
  • var 변수의 경우 중복 선언 허용
  • 만약, 스코프가 다르다면 같은 변수명을 선언해도 문제가 없으며 참조 시 같은 스코프에 있는 변수를 참조하게 된다.
  • var/let 을 조합한다고 해도, 같은 스코프에 저장되는 변수기 때문에 중복 선언이 안된다.

흠 하위 호환성을 생각하면 var 변수를 써야 할꺼 같은데, 만약 개발하는 환경이 ES6 코드가 정상적으로 굴러갈 수 있는 환경이라면 적극적으로 let 키워드를 통하여 변수를 선언하는 것이 유리할꺼 같다.

const 상수 생성

C,C++,Java 같은 언어에는 상수를 저장할 수 있는 문법적인 요소를 지원하고 있는데 자바스크립트를 그런 부분에 대한 지원이 전혀 없었다. 그래서 대부분 코드 컨벤션을 대문자로 잡거나 하는 방법으로 나름대로 상수를 식별하는 경우를 많이 봤었다.

var 변수의 경우 스코프의 변수 변경이 가능하다는 점 때문에 기존 코드에서는 상수 운영 시 변경에 대한 위험이 있었다고 할 수 있겠다.
ES6에서는 이런 상수에 대한 문법적인 지원을 포함하였는데, 그것이 바로 const 키워드이다.

쉽게 생각하여 읽기 전용 변수라고 보면 좋을꺼 같은데, 앞서 let 변수 선언의 특징을 설명했었는데 const는 이런 let 변수의 성격에 변경이 불가능한 ‘읽기전용’이라는 성격이 들어간다.

1
2
const ABS = 10;
ABS = 20;
1
2
[출력 결과]
TypeError: Assignment to constant variable.
1
2
3
4
5
6
7
const ABS = 10;
console.log(ABS);
function printAbs(){
const ABS = 20;
console.log(ABS);
}
printAbs();
1
2
3
[출력 결과]
10
20

읽기 전용 변수의 성격이라서 값을 다시 할당하는 것은 불가능하다.
그리고 let 변수의 성격처럼 블록 단위의 스코프를 지원하기 때문에 같은 변수명을 사용하더라도 스코프가 다르면 사용이 가능하다.

앞에서 let/const 의 간단한 성격을 설명했는데, 값을 직접 할당하는 방식으로 사용했기 때문에 실제로 코드를 작성할때 참조 타입의 데이터(객체,함수,배열)이 들어갔을 경우에 어떻게 되는지 궁금할 수 있다.
기본적으로 참조 타입은 데이터의 주소 값을 저장하는 점을 잘 기억하면 좋을꺼 같다.

다른 언어들도 거의 비슷하기 때문에, 경험 많은 분들이면 쉽게 이해할 수 있을꺼 같아요.

1
2
3
const arr = [10,20,30,40];
arr[0] = 100;
console.log(arr);
1
2
[출력결과]
[ 100, 20, 30, 40 ]

const는 읽기 전용이라고 했는데, 왜 변경이 되는지 잘 생각해보면 쉽게 답이 나온다. 실제로 arr의 참조 값을 바꾸는 것이 아니기 때문에 해당 참조 타입의 데이터의 인덱스/프로퍼티를 수정하더라도 기존 참조 타입의 데이터를 사용하듯이 추가/변경이 가능 한 것이다.

쫌 어려운 말로 const 변수가 객체 타입이더라도, 객체 자체는 가변(mutable) 상태인 것이다. 다른 언어들에서는 Mutable / Immutable 상태에 따른 변수를 선언하는 방식도 사용하고 있고 변경이 가능하냐 불가능하냐고 중요한 부분이기 때문에 해당 키워드를 검색해보는 것도 좋은 공부가 될꺼 같다.

예제는 물론 배열로 선언했지만 객체 역시도 동일하게 적용된다. 사용해야 할 목적과 이유는 분명한거 같다.
객체 자체의 변경이 없어야 할 경우 const 변수와 참조 타입을 적절하게 조합하여 사용하면 기존 var 변수로 선언했던 방식보다 좀 더 수월하게 개발이 가능한 것이다.