IT/JavsScript

var, let, const 바르게 사용하기

라임웨일 2021. 3. 30. 12:49
반응형

 

ES6에서 새롭게 추가된 변수 선언 방식 let, const와 기존 ES5에서 사용하던 변수 var가 어떠한 차이점이 있고 어떻게 사용해야 하는지 알아보려고 합니다.

 

스크립트에서 값을 할당하는건데 그렇게 꼭 구분을 지어야 하나? 아무거나 사용하면 안 돼?라고 생각하시는 분들도 있을지 모르겠어요. 하지만 무엇이든 이유 없이 탄생하는 문법은 없고 새로운 문법이 탄생하는 이유는 지금보다 더 나은 코드를 사용하기 위해서이기 때문에 우리는 목적에 맞게 해당 문법을 사용해야 합니다.

 

기존 자바스크립트에서 변수를 선언하는 방식은 "var" 오직 하나였습니다.

처음에는 한 가지 방법으로만 사용하니 편하다고 생각할지도 모르지만 이 방법은 편안함보다는 코드상에서 더 큰 문제점들을 만들었습니다.

 

 

ES5의 "var"에 대한 특징

1. 함수 스코프(function-scoped)

함수 스코프의 정의는 "함수 내에서 선언된 변수는 함수 내에서만 유효하며 함수 외부에서는 참조할 수 없습니다.  함수 내부에서 선언한 변수는 지역 변수이며 함수 외부에서 선언한 변수는 모두 전역 변수"라고 정의하고 있습니다.

 

말이 너무 어려워요. 우선 아래 예제를 한번 볼게요.

var foo = 'a';        // 전역 변수
console.log(foo);     // a

{
    var foo = 'b';    // 지역 변수
    console.log(foo); // 'b'
}
console.log(foo);     // 'b'

위의 코드를 보고 뭔가 이상함을 느끼지 않으셨나요?  이상함을 느끼셔야 합니다.

분명 최초 선언한 변수의 값은 "a"이고 함수 안에서만 사용할 목적으로 지역변수에 값을 할당하고 다시전역 변수를 호출하니

우리가 원하는 값은 "a"였는데 함수에서 선언한 "b"값이 나왔습니다.

결과는 전혀 다르죠. 이게 첫 번째 var의 문제점입니다. 

2. 키워드 생략 허용

var 키워드를 사용하지 않아도 변수가 허용됩니다. 암묵적 전역 변수를 양산할 가능성이 큽니다.

foo = '변수없이 선언'; 
console.log(foo) // "변수없이 선언"

3. 중복 선언 허용

변수를 최초 선언한 후 동일한 변수에 한 번 더 값을 선언했음에도 불구하고, 에러가 나오지 않고 각기 다른 값이 출력되는 것을 볼 수 있습니다. 유연한 변수 선언은 간단한 코드에서는 편리할 수도 있겠지만 이는 우리가 원치 않고 예상하지 못한 값의 변경을 가져올수도 있고 코드 양이 많아지면 어느 곳에서 잘못되었는지 파악하기도 힘듭니다.

 

var name = '최초 선언한 변수'
console.log(name) // 최초 선언한 변수

var name = '두번째 재할당 변수'
console.log(name) // 두번째 재할당 변수

 

4. 변수 호이스팅

스코프의 선두에서 선언 단계와 초기화 단계가 실행되기 때문에 변수 선언문 이전에 변수를 참조할 수 있습니다.

아래 예제는 변수를 선언하지 않았음에도 최초에 변수값을 호출하면 "undefined" 값이 노출되는 것을 알 수 있습니다.

console.log(foo); // undefined

var foo;
console.log(foo); // undefined

foo = 1; // 할당문에서 할당 단계가 실행
console.log(foo); // 1

 

5. 반복문에서 var의 유효 범위

var a = 10;
for (var a = 0; a < 5; a++) {
    console.log(a); // 0 1 2 3 4
}
console.log('out side a:' + a); // out side a : 5

var a = 10; 로 변수 a를 선언한 상태에서 for 반복문에 동일한 변수 이름 a를 사용했습니다. 이렇게 되면 {} 으로 변수의 유효 범위가 제한되지 않기 때문에 for 반복문이 끝나고 나서 console.log(a); 를 출력하면 for 반복문의 마지막 결과 값이 출력됩니다. 이런한 문제점을 해결하기 위해 ES6에서 const, let이라는 변수가 탄생했습니다.

 

ES6  "let, const"의 변경점

1. 블록 레벨 스코프(Block-level scope)

위에서 본 것처럼 var의 함수 스코프의 단점을 보안하기 위해 ES6에서 생겨난 let, const는 블록 스코프(block-scoped)입니다. 모든 코드 블록(함수, if 문, for 문, while 문, try/catch 문 등) 내에서 선언된 변수는 코드 블록 내에서만 유효하며 코드 블록 외부에서는 참조할 수 없습니다.

let foo = '최초 선언 전역변수'; // 전역 변수

{
    let foo = '최초 선언 지역변수1'; // 지역 변수
    let bar = '최초 선언 지역변수2'; // 지역 변수
    console.log(foo); // 최초 선언 지역변수1
	console.log(bar); // 최초 선언 지역변수2
}

console.log(foo); // 최초 선언 전역변수
console.log(bar); // ReferenceError: bar is not defined
let a = 10;
for (let a = 0; a < 5; a++) {
    console.log(a); // 0 1 2 3 4
}
console.log('out side a :' + a); // out side a :10

위의 var함수와 다른 점이 보이시나요? 두 차이점이 보이신다면 여러분은 내용을 잘 이해하고 따라오고 계신거에요.

2. 변수 중복 선언 불가

ES6에서는 한번 선언된 변수에 중복 선언을 하지 못하게 하였습니다.

let foo = "최초 선언";
let foo = "다시 변경 선언" // Identifier 'foo' has already been declared

3.호이스팅 불가(호이스팅 보완)

var와 달리  let과 const는 변수 선언문 이전에 변수를 참조할 수 없습니다.

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

let foo; // 변수 선언문에서 초기화 단계가 실행된다.
console.log(foo); // undefined

foo = 1; // 할당문에서 할당 단계가 실행된다.
console.log(foo); // 1

 

let과 const의 차이점

그렇다면 let과 const의 차이점은 무엇일까요? 이 둘의 가장 큰 차이점은 immutable (불변성) 여부입니다.

"immutable"이라는 개념은 추후 배열이나 Object에서 값을 할당할 때 아주 중요한 요소입니다. React에서도 마찬가지죠.

immutable이라는 주제만으로도 글을 정리할 수 있을 만큼 중요한 요소이니 관심 있으신 분들은 한번 자바스크립트 immutable에 대해서도 한번 검색해보시고 이해하시면 좋을 것 같아요.

 

그럼 다시 본론으로 넘어와서 이 둘의 가장 큰 차이점은 immutable이라고 말씀드렸죠.

"let" 은 변수에 값을 재할당이 가능하지만, const는 변수 재선언, 변수 재할당 모두 불가능합니다.

 

- let 값 할당.

let name = '기존 값' ;
console.log(name) // a

let name = '새로운 값';
console.log(name) // Uncaught SyntaxError: Identifier 'name' has already been declared :  재할당 불가 

name = '새로운 값';
console.log(name) // 새로운 값

- const 값 할당

const name = '기존 값';
console.log(name) // 기존 값

const name = '새로운 값';
console.log(name) // Uncaught SyntaxError: Identifier 'name' has already been declared 

name = '새로운 값';
console.log(name) //Uncaught TypeError: Assignment to constant variable.

단, 객체 {}또는 배열 []로 선언했을 때는 객체의 속성(property)과 배열의 요소(element)를 변경할 수 있습니다.

// 객체로 선언하고 속성 값을 변경
const b = {
    num: 10,
    text: 'hi'
};
console.log(b.num); // 10

b.num = 20;
console.log(b.num); // 20
// 배열로 선언하고 배열 요소를 추가
const c = [];
console.log(c); // []

c.push(10);
console.log(c); // [10]

 

var를 이용한 변수 선언 방식과 let & const를 이용한 변수 선언 방식을 알아봤습니다.

어떤 변수 선언 방식을 써야 할까 고민이 되시나요? 이런 고민을 하신다면 이제는 보다 좋은 코드를 사용할 준비가 된 것입니다. 

변수 선언에는 기본적으로 const를 사용하고, 재할당이 필요한 경우에 한정해 let을 사용하는 것이 좋습니다. 이때, 변수의 스코프는 최대한 좁게 만듭니다. const를 사용하면 의도치 않은 재할당을 방지해 주기 때문에 우리가 원치 않는 값의 변경을 막게 되어 코드의 안정성을 높입니다.

 

감사합니다.

반응형
광고차단(애드블록)프로그램이나 브라우저를 사용중이시면 프로그램을 비활성화이나 블로그 주소를 예외 처리 해주시면 광고가 노출됩니다. 귀찮고 번거롭겠지만 광고 클릭은 저에게는 큰 힘이 됩니다. 🙇🏻‍♂️🙇🏻‍♀️
제 블로그의 모든 글은 제가 직접 작성 하고 다른 글을 참고할 때는 이전 글보다 읽기 편하게 수정해서 작성하고 있습니다. 커피 한잔 사먹고 더 열심히 좋은글로 보답하겠습니다.
오늘도 제 블로그에 와 주셔서 감사합니다. :)
//