[JavaScript] 변수에 대해 (let, const, var)

김효선·2021년 7월 11일
0

JavaScript 파악하기

목록 보기
1/1
post-thumbnail

자바스크립트 변수(variable)

📔 변수 구분

변수는 크게 선언되는 위치에 따라 로컬(지역)변수글로벌(전역)변수로 나뉜다.

전역 변수(Global variable)

  • 공통적으로 사용하는 변수로 프로그램 자체에서 접근이 가능한 변수.
let a = 1;
function myFunction() {
  console.log(a);
}
myFunction(); // 1

변수 a는 블록 밖에 선언된 전역 변수로 함수 블록 안에서도 접근이 가능하다.

지역 변수(Local variable)

  • 가까운 스코프 내에 존재하는 변수.
let a = 1;
function myFunction() {
  let a = '하나';
  console.log(a);
}
myFunction(); // '하나'
console.log(a); // 1

블록 안에서는 밖에 있는 변수와 동일한 이름의 새 변수를 선언할 수 있다.

즉, 블록 내부에 선언된 지역 변수가 있는지 확인하고 있으면 해당 지역 변수를 사용, 없으면 블록 밖에 있는 전역 변수를 사용하게 된다.


📔 변수 선언

자바스크립트에는 3가지의 변수 선언 방법이 있다.

  1. let
  2. const
  3. var

let 변수

블록 스코프를 가진 변수

let a;
let name = '효선';
let age = 27, gender = '여성';
  • 값을 할당하지 않아도 된다.
  • 콤마로 구분하여 여러 개의 변수를 선언할 수 있다. 대신 let 키워드는 맨 앞에 한번만 작성해야한다.

var 변수

블록 스코프가 없는 변수
-> var 로 선언한 변수의 스코프는 함수 스코프이거나 전역 스코프이다.

반복문 예시)
for (var i = 0; i < 10; i++) {
  // ...
}
console.log(i); // 10 반복문이 종료되었지만 전역 스코프이므로 접근이 가능하다.
함수 스코프 예시)
function myVar() {
  if(true) {
    var name = '효선';
  }
  console.log(name);
}
myVar(); // 효선
console.log(name); // 출력되지 않는다.

const 변수

값을 바꿀 수 없는 변수 선언. (상수)

const a; // SyntaxError: Missing initializer in const declaration

  • const 변수는 반드시 선언과 동시에 할당이 이루어져야한다
const BIRTHDAY = 950218;
BIRTHDAY = 931226; // TypeError: Assignment to constant variable.
  • 재할당도 할 수 없다.

📔 window 객체(Global object)

window 객체는 브라우저의 요소들과 자바스크립트 엔진, 그리고 모든 변수를 담고 있는 객체이다. 글로벌 객체로 부르기도 한다.

var food = '음식';
let animal = '동물';

console.log(this.food, this.animal);// 음식, undefined
// window객체에 들어가므로 window.food 로 사용할 수도 있다.
  • 글로벌 스코프에 선언된 var 변수는 this로 참조할 수 있지만 let은 그렇지 않다.
  • 글로벌 스코프에 선언된 let 변수는 엔진이 블록을 만들고 이를 스코프로 사용한다.

📔 호이스팅(Hoisting)

💡 변수나 함수의 선언이 최상위로 끌어올려지는 현상, 변수가 함수 내에서 선언된 지역 변수이면 함수 내의 최상위, 글로벌 스코프에 선언된 전역 변수이면 전역 컨텍스트 최상위로 끌어올려진다.

함수 선언문 호이스팅은 따로 다룰 예정이다.

var 변수의 호이스팅

  • 모든 var 변수는 할당하기 전까진 값이 undefined 이다.
  • 선언은 호이스팅 되지만 할당은 호이스팅 되지 않는다.
console.log(food); // undefined
var food = '음식';

var 변수는 아래에 선언되어있지만 선언이 위로 끌어올려지면서 food의 값을 undefined로 출력할 수 있다.

위 코드를 풀어보면, 아래와 같이 실행된다고 볼 수 있다.

var food;
console.log(food); // undefined
food = '음식';
console.log(food); // 음식

let/const 변수의 호이스팅

console.log(animal); // ReferenceError
let animal = '동물';

let과 const에선 ReferenceError가 발생한다. 이는 TDZ(Temporal Dead Zone)에 영향을 받기 때문에 var 변수와는 다르게 작동한다.

❗ 흔히들 let과 const는 호이스팅이 되지 않는다고 생각할 수 있지만.. let과 const도 변수도 호이스팅이 된다!!!!

⚠ TDZ(Temporal Dead Zone)?

직역하면 일시적인 사각지대 라는 뜻인데 이 일시적인 사각지대는 스코프의 시작 지점부터 초기화 시작 지점까지의 구간을 말한다.

변수 생성의 3단계

💖 선언 단계(Declaration phase)

-> 변수를 실행 컨텍스트의 변수 객체에 등록하는 단계!
이 변수 객체는 스코프가 참조하는 대상이 된다.

🧡 초기화 단계(Initialization phase)

-> 실행 컨텍스트에 존재하는 변수 객체에 등록된 변수를 위한 메모리를 만드는 단계!
이 단계에서 변수는 undefined로 초기화된다.

💛 할당 단계(Assignment phase)

-> undefined로 초기화된 변수에 다른 값을 할당하는 단계

📃 var 변수의 경우 선언과 초기화를 동시에 진행한다. 메모리를 할당해주고 undefined로 초기화되기 때문에 호이스팅될 때 에러가 나지 않는다.

📃 let 변수의 경우 선언과 초기화를 따로 진행한다. 선언 단계에서 변수가 등록되지만 초기화 단계는 변수 선언문에 도달했을 때 이루어지기 때문에 그 전에 변수에 접근하려하면 ReferenceError 가 발생한다. *변수를 위한 메모리 공간이 확보되지 않았기 때문.

console.log(animal); // ReferenceError

let animal; // 변수 선언문에서 초기화 단계
console.log(animal); // undefined

animal = '동물'; // 할당문에서 할당 단계
console.log(animal); // 동물

📃 const 변수의 경우 var 변수처럼 선언과 초기화를 동시 진행하지만 선언 이전에 TDZ가 생성되어 접근하면 ReferenceError 가 발생한다. 반드시 선언과 동시에 할당도 해줘야한다


취업을 하기 전 한 회사에서 면접을 보았는데 let과 const가 호이스팅이 되느냐란 질문에 안된다고 대답했었다. var변수만 된다고 대답했었다.. TDZ에 대해서도 물어보셨는데 대답을 하지 못했던 기억이 있다.... 변수는 그냥 일상 생활에서 사용하듯이(?) 써서 TDZ에 대해 깊게 다뤄보지 못했었는데 이제와 생각해보면 참 리액트 공부하는데에만 급급했구나 싶다.. 그 후에 TDZ가 뭔지 알아보았는데 이번 회사에서 동료들이랑 자바스크립트 스터디를 시작한 김에 공부한 것을 블로그에 정리하면 좋을 것 같아서 적어보았다.

그리고 결론 .... 처음 자바스크립트 공부 시작할 때 es6부터 바로 해서 var 변수는 사용한 적도 없었는데 더더욱 쓰지 말아야겠다는 생각이 들었다.

profile
차근차근 나아가는 주니어 프론트엔드 개발자

0개의 댓글