변수의 대해(2)

Bonggus·2021년 10월 22일
0

자바스크립트

목록 보기
6/23
post-thumbnail

Var를 지양하자

let, const가 나오기 이전에는 var를 사용했다. 그렇다면, var와 let, const의 차이는 무엇일까. 핵심은 var는 함수스코프, let, const는 블록단위 스코프를 가진다는 것이다. 그 외에도 선언, 할당, 호이스팅 등의 특징을 발견할 수 있다.

기본

var

  • 재선언 가능
  • 재할당 가능
  • 변수 출력보다 나중에 선언 및 할당해도 오류가 나지 않는다(호이스팅 O)
  • 전역공간에 저장됨

let

  • 재선언 불가
  • 재할당 가능
  • 호이스팅 X

const

  • 재선언 불가
  • 재할당 불가
  • 호이스팅 X

스코프차이

var

블록 안에서 변수를 변경하면, 전역공간의 변수까지 변경된다. 그 이유는 var는 함수단위 스코프를 가지기 때문이다.

let, const

let/const는 블록단위로 변수의 범위가 지정된다.

전역공간 최소화 이유

전역공간은 사용하면 안될까? 그렇다면 그 이유는 무엇인가? 어디서나 접근이 가능하기 떄문이다. 사람이 생각하기에 분리되어있다 생각하지만, 실행혼경에서는 분리되어있지 않다. 핵심은 의도치 않는 에러가 발생하기 때문이다.

그래서, 에러를 방지하기 위한 방안으로는 전역변수를 사용하지 않는다. window/global을 조작하지 않는 것이다. const/let을 사용함으로 var가 전역에 생성하는 데이터를 줄일 수 있다. 보다 근본적으로
IIFE, Module, Closure를 통해 스코프를 나누는 방법이 있다.

전역공간?

전역공간은 대체로 최상위를 의미한다. window 혹은 global 이라고 하는데 브라우저 환경에서는 window, node환경에서는 global이 전역공간이다.

왜 글로벌을 침범하면 안되는가?

JS는 파일을 나눠도 스코프가 나뉘어지지 않는다.

<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <script src="./global.js"></script>
  <script src="./global2.js"></script>
</body>
</html>
// global
var global = 'global';

console.log(console.log('global', global));
// global2
console.log('global2', global);

또한 전역객체에 이미 등록되어있는 기능들과 같은 이름의 변수를 선언/할당하면, 그 기능에 덮어서지는 문제가 생긴다. 브라우저 콘솔에는 에러가 찍히지만, 노드 환경 내에서는 에러가 생기지 않는다.

// global
var global = 'global';

console.log(console.log('global', global));

var setTimeout = 'setTimeout';
// global2
console.log('global2', global);

setTimeout(() => {
  console.log(1);
}, 1000);

호이스팅

호이스팅은 런타임 시기에 선언과 할당이 분리된 것이다. 런타임 시기는 코드가 동작될 떄는 의미한다. 호아스팅은 변수가 초기화가 제대로 되어있지 않을 때 undefined로 최상위에 끌어올려질 수 있는 것을 의미한다. 특히 var를 사용할 때 발생가능하다.

var globa = 0;
function outer() {
  console.log(global); // undeinfd > 선언과 할당이 분리된 상태
  var global = 5;

  function inner() {
    var global = 10;
    console.log(global); // 10
  }

  inner();

  global = 1;
  
  console.log(global); // 1
}

outer();

변수뿐만 아니라 함수 역시 호이스팅이 된다.

console.log(sum()); // 3

function sum() {
  return 1 + 2;
}

해결책 중 하나는 함수표현식을 사용하는 것이다.

console.log(sum()); // Error

const sum = function() {
  return 1 + 2;
}

호이스팅은 런타임시 선언이 최상단으로 끌어올려지는 것을 의미한다. 문제는 코드 작성시 예측하지 못한 실행결과가 나올 수 있다. 이것을 피하기 위해 var를 사용하지 말아야 한다. 그리고 함수도 호이스팅이 되기 때문에 함수 표현식을 통해 호이스팅을 방지할 수 있다.

let/const선언 변수는 호이스팅되지 않는 것이 아니다. 스코프에 진입할 때 변수가 만들어지고 TDZ(Temporal Dead Zone)가 생성되지만, 코드 실행이 변수가 실제 있는 위치에 도달할 때까지 액세스할 수 없는 것이다. let/const변수가 선언된 시점에서 제어흐름은 TDZ를 떠난 상태가 되며, 변수를 사용할 수 있게 된다.

TDZ(Temporal Dead Zone)

TDZ는 선언 전에 변수에 접근하는 것을 금지한다.

출처

profile
프론트엔드

0개의 댓글