JS - var, let, const는 무엇인가?

김지현·2021년 5월 30일
9

Javascript

목록 보기
2/3
post-thumbnail

var, let, const

✔️ 우리가 자바스크립트에서 어떤 로직을 구성할 때, 가장 첫 번째로 하는 것이 바로 변수 생성일 것이다. 자바스크립트에서 변수를 생성하는 방식으로는 var, let, const가 있다.

그렇다면 이 세 가지 방식의 차이가 무엇인지 파헤쳐보자!


var

1. 재할당 및 재선언이 가능한 선언 방식

var는 기존의 자바스크립트에서 사용되어 오던 방식이다. 여기서 기존이라 함은, ES6 (ES2015) 이전에 사용되어 오던 구 방식이라고 생각하면 된다.

자바스크립트는 다른 언어와는 다르게, 매우 관대한 언어이다.

이 점은 유연한 코드 작성이 가능하다는 장점이 있으나 개발자들을 매우 피곤하게 만든다는 치명적인 단점이 존재한다.

이러한 단점을 극명하게 증명해주는 것이 바로 'var'이다.

var person = 'hong gil dong';
console.log(person); // hong gil dong

var person = 'kim gil dong';
console.log(person); // kim gil dong

person = 'lee gil dong';
console.log(person); // lee gil dong

person값을 처음 선언하고 'hong gil dong'이라는 값을 주었음에도 불구하고, 다시 person을 선언하고 'kim gil dong'이라는 값을 주어도 오류 없이 잘 출력되는 모습을 볼 수 있다.

또한 'lee gil dong'이라는 값을 재할당해주어도 오류 없이 잘 출력되는 것을 볼 수 있다.

이런 식으로 var를 사용한 변수 선언은 재할당 및 재선언이 가능하다.

이러한 var의 관대한 선언 방식은 짧고 간결한 코드 작성 시에는 크게 영향이 없겠지만, 여러 개발자들이 협업을 하거나 큰 규모의 프로젝트 진행 시, A라는 개발자가 선언해둔 변수가 있고 B라는 개발자가 그 변수명과 같은 이름을 써서 선언해도 오류가 나지 않는다는 대참사를 발생시킬 수 있다.

이는 후에 코드의 유지보수 및 디버깅 시에 굉장한 문제를 일으킬 것이다.
더불어 변수의 남용 가능성을 남기기 때문에 되도록이면 var을 사용한 변수 선언은 피하는 것이 좋겠다.


2. Function level scope

var는 'function level scope'이다. 약간 생소할 수도 있는 function level scope이 과연 무엇인가에 대해 알아보도록 하자.

우선 이 개념에 대해서 설명하기 전에, 자바스크립트에는 'scope'라는 개념이 존재한다.

전역 변수, 지역 변수로 나뉘며 이 둘을 나누는 기준은 {}, 즉 block이다. block 내에서 선언된 변수는 지역 변수(local variable), block 밖에서 선언된 변수는 전역 변수(global variable)이라고 칭한다.

하지만 var는 block level scope를 따르지 않고, function level scope를 따른다.

즉, 함수 내에서 선언된 변수를 지역 변수라고 칭하며, 함수 밖 및 함수를 제외한 범위에서 선언된 변수를 전역 변수라고 부른다는 의미와 같다.

먼저 하나의 예시를 살펴보자.

function person(){ 
  var name = 'gil dong'; 
  console.log(name); 
} 

person(); // gil dong
console.log(name); // ReferenceError: a is not defined

위 코드를 분석해보면,

person이라는 함수 내에서 선언된 var는 함수 내부에서만 출력 가능하며, 함수 밖에서 출력하려고 하면 참조가 불가능하다는 에러가 뜬다.
즉, 함수라는 scope내에서 선언한 변수의 경우, 함수 밖에서는 참조가 불가능하다.

그렇다면 또 다른 예시를 살펴보자.

if (true) {
  var myName = 'gil dong';
  console.log(myName); // gil dong
}

console.log(myName); // gil dong

위 코드를 분석해보면,

if문 안에서 var를 통해 변수를 선언했다.
그리고 if문 안과 밖 모두에서 변수의 값을 출력했더니, 모두 정상적으로 출력이 되는 모습을 볼 수 있다. if문과 같이 함수가 아닌 경우, var를 통해 선언한 변수는 모두 전역 변수로 간주하므로 어디서든 출력이 가능한 것이다.

이것이 얼마나 말도 안되는 상황인가?

엄격한 변수 선언 방식을 가진 언어를 배우던 사람이 자바스크립트의 var를 처음 접하게 되면 아마 적지 않은 충격을 받을 것이라고 예상한다. 😂

이것은 var 사용을 지양해야 하는 또 다른 이유다.


3. Hoisting

🚀 호이스팅이란, var 변수의 선언 및 함수의 선언이 가장 위로 끌어올려지는 것을 말한다.

var를 통한 변수 선언은 이 호이스팅의 개념으로 인해 변수가 선언되기도 전에 참조하는 것이 가능하다. 바로 예시를 통해 살펴보자.

console.log(greeting); // undefined
var greeing = 'hi'; 

console.log(greeting); // hi

위 예시를 보면, var를 통한 변수의 선언도 전에 greeting이라는 변수를 먼저 호출했다. 하지만 에러가 뜨지 않고, 'undefined'가 출력되었다.

이러한 말도 안되는 현상이 발생하는 이유가 무엇일까?

✔️ var를 통해 변수를 선언하면,

1️⃣ 변수를 선언한다.
2️⃣ undefined로 미리 초기화 한다.

위의 호이스팅 방식으로 인해서 변수의 선언도 전에 참조가 가능한 것이다.


4. 전역 객체의 property 여부

var를 통해서 선언된 변수는 전역 객체(Global Object), 브라우저 환경으로 예를 들면 'window' 객체의 property 값으로 할당된다.

반면, let과 const는 전역 객체의 property로 할당되지 않는다.

바로 예시를 들어보자.

var myAge = 25;

console.log(myAge); // 25
console.log(window.myAge); // 25

'window'라는 전역 객체를 통해 age에 접근 했을 때, 25라는 값이 출력되는 것을 알 수 있다. 이는 var를 통해 선언된 변수가 window 객체의 프로퍼티 값이라는 것을 증명한다.

반면,

let age = 25;

console.log(age); // 25
console.log(window.age); // undefined

let, const를 사용해 선언된 변수는 window 객체를 사용해 접근 했을 시 undefined가 출력된다.


let

1. 재할당이 가능한 선언 방식

let은 재할당은 가능하지만, 재선언은 불가능한 선언 방식이다.

let flower = 'sunflower';
console.log(flower); // sunflower

flower = 'rose';
console.log(flower); // rose

위 코드처럼, 재할당이 가능하며 정상적으로 출력된다.

let flower = 'sunflower';
let flower = 'cherry blossoms';

console.log(flower); // SyntaxError: Identifier 'flower' has already been declared

하지만 재선언 시, 'flower'이라는 이름의 변수는 이미 선언되었다는 에러 문구가 표시된다.


2. Block-level scope

위에서 var를 통한 선언은 function level scope라고 설명했다.

반면 let, const는 기존에 우리가 알던 개념처럼 block-level scope이다.
block 내에서 선언된 것은 지역 변수, block 외에서 선언된 것은 전역 변수가 된다.

if(true) {
  let dish = pasta;
  console.log(dish); // pasta
 }
 
 console.log(dish); // ReferenceError: dish is not defined

if문 내에서 변수를 선언해도 if문 밖에서 그 변수를 참조할 수 있었던 var와는 다르게, let을 사용하면 그것이 if문이라고 할 지라도 참조 불가능하다.
이는 var은 function level scope이고, let은 block level scope이기 때문이다. const도 마찬가지이다.

사실 이것이 당연한 개념이지만, var는 당연하지 않은 것들을 당연한 것처럼 만들어주는 굉장한 능력이 있다. 😇

function cook () {
  let dish = pasta;
  console.log(dish); // pasta
 }
 
 console.log(dish); // ReferenceError: dish is not defined

또한 당연히 함수 내에서 let을 통해 변수를 선언하고, 그 변수를 함수 밖에서 참조하려고 하면 오류가 표시된다. 이는 var, let, const 모두 동일한 부분이다.


3. 선언 전 참조가 불가능한 선언 방식

이것 또한 var과는 대비되며 let, const 모두에 적용되는 사항이다!

var는 변수의 선언 전에 참조가 가능했으나, let과 const는 절대 불가능하다.
바로 예시를 들어보자.

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

let favorite = 'food';

let을 사용한 선언 방식은 변수 선언 전에 변수에 접근하려고 하면 오류가 발생한다.
이는 호이스팅 방식에서 오는 차이 때문이다. var, let, const 모두 호이스팅이 발생하지만 그 방식이 var과 let/const는 다르다.

let 및 const는 코드가 실행되기 전에는

1️⃣ 변수의 선언을 한다.
2️⃣ 변수 선언문을 만났을 시 초기화가 발생한다.

위 호이스팅 방식으로 인해 변수의 선언 전에는 참조가 불가능한 것이다.


const

1. 재할당, 재선언 모두 불가능한 선언 방식

const는 가히 가장 엄격한 변수 선언 방식이라고 할 수 있다.

const를 통해 변수 선언을 하면 재할당 및 재선언이 모두 불가능하다.

앞서 언급했지만, var의 유연함은 곧 독이 될 수 있다. 따라서 이 엄격함이 코드를 작성하고 유지 보수 하는 데 훨씬 더 편리하다.

const city = 'Ulsan';
console.log(city); // Ulsan

city = 'Busan';
console.log(city); // TypeError: Assignment to constant variable.

const city = 'Seoul';
console.log(city); // SyntaxError: Identifier 'city' has already been declared

const를 사용해서 변수를 선언하면 재할당, 재선언 시 모두 오류가 발생한다.
따라서 const는 변수의 값이 변하지 않는 상황에 사용하는 것이 바람직하다.

만약 값을 변경 해주어야 하는 상황이 온다고 해도, const를 let으로 변경하는 것은 어렵지 않다. 그런데 변경을 하면 안되는 상황에서 변경이 되어버렸다면?

📍 const를 let으로 변경해줌으로서 발생하는 약간의 귀찮음보다, 어디서 오류가 나는 지도 모른 채 지나가는 것이 훨씬 더 큰 위험성을 안고 있다는 것을 명심해야 한다! 🤯


2. Block-level scope


3. 선언 전 참조가 불가능한 선언 방식

const - 2, 3번은 이미 let chapter에서 설명했으므로 생략하도록 한다.


정리하면, 변수의 선언 시에는 디폴트로 const를 사용하도록 하자.

const는 가장 엄격한 변수 선언 방식이므로, 사람인 우리가 어쩔 수 없이 저지를 수 있는 어떠한 실수를 미연에 방지하는 역할을 한다.

우리가 알파고처럼 기억력이 좋아서 이전에 사용했던 모든 변수명을 기억하고 있다면 말이 달라지겠지만 그것은 불가능에 가깝다.

따라서 스스로 코드들을 점검하여 중복이 있다면 에러 표시를 해주고, 수정을 요구하는 const의 사용을 통해서 좋은 코드, 유지 보수가 쉽고 편리한 코드 작성을 할 필요가 있다.

위에서도 언급했지만, const로 선언한 변수에 재할당 등이 필요한 상황이 생기면 그 때 let으로 변경해주도록 하자. 이미 구 방식이 되어버린, 그리고 너무나 많은 오류와 불편함을 초래하는 var의 사용은 최대한 지양하자. (사실 최대한 ❌ 절대 🆗)

하지만 아직은 오래 전에 작성된 코드를 기반으로 한 웹 사이트가 많으므로, 최소한의 용도와 쓰임새 등에 대해서는 알아두어야 하니 var에 대한 정보를 잊는 건 안된다!


✨ TIL을 마무리하며

var, let, const에 대한 개념은 자바스크립트의 기본 중의 기본이라고 생각한다!
하지만 기본일 수록 쉽게 생각하고 지나칠 수 있기 때문에, 더 탄탄히 다지고 지나가야 한다. 이번 글을 작성하면서 다시금 var, let, const의 개념에 대해 정리하고 짚고 넘어갈 수 있어서 너무 좋았다!

앞으로도 쉽다고 지나치지 않고 오히려 쉬운 개념이니까 다시 한 번 짚고 넘어가는 꼼꼼한 개발자의 자세를 가져야겠다. 💪

profile
나만의 세상을 개척하고 싶은 사람

4개의 댓글

comment-user-thumbnail
2021년 5월 30일

믿고 보는 지현님의 포스팅💖 깔끔한 정리 너무 잘읽었습니다! 덕분에 공부가 되었어요!!

1개의 답글
comment-user-thumbnail
2021년 6월 1일

여태 봤던 관련 글 중 가장 이해가 잘되는 것 같습니다. 감사합니다.

1개의 답글