티스토리 뷰

변수는 이름을 통해서 어떤 값에 특별한 의미를 부여할 수 있는 하난의 상자라고 할 수 있습니다.

다르게 표현하면 프로그래밍에서 추상화의 가장 기본적인 수단이 바로 이 변수라고 할 수 있는데요.

자바스크립트에서 이 변수를 만드는 방법은 ES2015를 기준으로 약간의 변화가 있었습니다.

ES2015 이전에는 var라는 키워드를 사용해서 변수를 만들었었는데요.

// 변수와 스코프
var title = 'Codeit'

let age = 20;
const PI = 3.14;

그래서 ES2015에서는 var 키워드가 가진 문제를 해결하기 위해 let과 const라는 키워드가 등장했고 최근에는 var보다는 활용 목적에 따라서 값의 재할당이 필요한 경우에는 let 키워드를 재할당이 필요하지 않은 경우에는 const 키워드를 통해서 변수를 만드는 방식이 좀 더 권장되고 있습니다.

자 그럼 ES2015 이전과 이후에 변수 선언 키워드 사이에는 어떤 차이가 있는지 살펴보면서 앞으로 우리가 왜 변수를 선언할 때 let과 const를 사용해야 하는지 한번 더 명확하게 확인하는 시간을 가져봅시다.

 

첫 번째는 변수가 유효한 시점의 차이가 있습니다.

var 키워드는 변수를 만들기도 전에 사용이 가능한 문제가 있었는데요.

// 변수와 스코프
console.log(title); // undefined
var title;

이렇게 title이라는 변수를 만들기도 전에 콘솔창에 title을 출력했는데도 코드를 실행해보면 에러가 발생하는게 아니라 undefined 값이 출력되는 모습을 볼 수 있습니다. 이런 식으로 코드상에서는 선언이 분명히 나중에 되었지만 마치 이 선언이 위로 올라간 듯한 현상을 호이스팅(Hoisting)이라고 부르는데요.

// 변수와 스코프
console.log(title); // undefined
var title = '쑥쑥';
console.log(title); // 쑥쑥

참고로 호이스팅은 선언 부분만 끌어 올려지기 때문에 이렇게 변수 선언과 동시에 값을 할당하더라도 할당된 값 자체는 그 이후에 접근이 가능하다는 점도 참고해 두시면 좋을 것 같습니다.

// 변수와 스코프
console.log(title);
let title;

아무튼 이런 현상은 선언문만 호이스팅되기도 하고 코드를 작성할 때도 변수를 선언한 다음에 사용하면 큰 문제가 없긴 하겠지만 let이나 const 키워드는 애초에 변수 선언 이전에 접근할 수가 없기 때문에 이 코드를 실행해보면 '선언 이전에 접근할 수 없다'라는 에러 메세지가 나타납니다. 예상치 못한 오류가 발생했을 때 그 원인을 파악하기가 훨씬 더 수월하다는 장점이 있습니다.

// 변수와 스코프
var title = '쑥쑥';
console.log(title);
var title = 'JavaScript';
console.log(title);

그리고 두 번째는 중복 선언의 차이가 있는데요. var 키워드는 중복 선언이 가능하다는 문제가 있습니다. 이렇게 title이라는 변수를 두 번 선언해도 코드를 실행해보면 아무런 문제 없이 동작하는 모습을 볼 수 있는데요.

이게 무슨 문제인가 싶기도 하지만 '쑥쑥'이라는 문자열 값도 사용해야 되고 'JavaScript'라는 문자열 값도 사용해야 하는데 만약 이 두 선언 사이에 훨씬 더 많은 코드들이 있어서 실수로 이미 선언한 변수명을 중복으로 선언해 버리면 그 이후부터는 의도치 않게 위에서 선언한 '쑥쑥'이라는 값은 사라지게 되는 문제가 발생합니다.

// 변수와 스코프
let title = '쑥쑥';
console.log(title);
let title = 'JavaScript';
console.log(title);

반면에 let이나 const 키워드는 중복 선언이 불가능하기 때문에 let으로 바꿔서 코드를 실행해보면 나중에 같은 이름으로 변수를 선언하려고 하면 콘솔에 에러 메시지가 나타난 걸 확인할 수 있습니다.

심지어 친절하게 몇 번째 줄에서 에러가 났고 '같은 이름을 이미 선언된 변수가 있다'라고 알려줍니다.

 

마지막으로 가장 중요한 차이가 있는데요. 바로 변수의 유효 범위, 스코프(Scope)에 차이가 있습니다.

var 키워드는 변수의 스코프가 함수 단위로만 구분이 되는데요.

// 변수와 스코프
var x = 3; // Global Variable

function myFunc() {
  var y = 4; // Local Variable
  console.log(`x in myFunc: ${x}`); // x in myFunc: 3
  console.log(`y in myFunc: ${y}`); // y in myFunc: 4
}

myFunc();
console.log(x); // 3
console.log(y); // error

이 코드를 실행해보면 보시는 것처럼 x는 전역 변수이기 때문에 함수 안에서나 함수 밖에서나 자유롭게 사용이 가능하고 y는 함수의 지역 변수이니까 함수 밖에서는 사용할 수가 없습니다.

// 변수와 스코프
var x = 3;

if (x < 4) {
  var y = 3;
}

for (var i = 0; i < 5; i++){
  console.log(i);
} // 0 1 2 3 4

console.log('x:', x); // x: 3
console.log('y:', y); // y: 3
console.log('i:', i); // i: 5

그런데 var 키워드는 함수 단위로만 구분이 되기 때문에 이렇게 조건문이나 반복문 안에서 새로운 변수를 만들게 되더라도 모두 전역 변수로 평가되는데요. 어떤 조건문이나 반복문에서 고유하게 사용할 수 있는 지역변수는 만들 수가 없는 문제가 있던 것이죠.

이 부분을 해결하기 위해서 let과 const 키워드는 중괄호가 사용되는 부분을 기준으로 변수의 유효 범위를 구분하는데요. 자바스크립트에서는 이렇게 중괄호가 감싸진 부분을 '코드 블록'이라고 부릅니다.

// 변수와 스코프
let x = 3;

if (x < 4) {
  let y = 3;
}

for (let i = 0; i < 5; i++){
  console.log(i);
}

console.log('x:', x);
console.log('y:', y);
console.log('i:', i);

일단 여기에 있는 var 키워드를 모두 let 키워드로 바꿔서 코드를 실행해 볼 텐데요. 코드를 실행해보면 'y가 선언되지 않았다'라는 에러 메세지가 나타납니다. 여기 if문 안에서 let 키워드로 선언된 변수 y는 if문의 코드 블록 안에 있는 지역 변수로 평가됐기 때문에 if문 밖에서는 사용할 수 없게 된 겁니다.

// 변수와 스코프
{
  let title = '쑥쑥';
  console.log(title);
}

console.log(title);

심지어 let 과 const 키워드는 이렇게 어떤 문법에 해당하는 특별한 키워드 없이 단순히 코드 블록으로만 구분되어 있어도 모두 스코프를 구분하기 때문에 코드를 실행해보면 코드 블록 안에서는 '쑥쑥'이 잘 출력되지만 코드 블록 밖에서는 에러가 나타나는 모습도 확인할 수 있습니다.

// 변수와 스코프
var x; // 함수 스코프 (function scope)
let y; // 블록 스코프 (block scope)
const z; // 블록 스코프 (block scope)

그래서 var 키워드는 함수를 기준으로만 스코프가 결정되기 때문에 '함수 스코프'를 가지고 let과 const 키워드는 코드 블록을 기준으로 스코프가 결정되기 때문에 '블록 스코프'를 가진다 라고 표현하는 부분도 함께 기억해 두면 좋을 것 같습니다.

 

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함