[딥다이브] 전역변수와 블록 레벨 스코프

Dongs·2023년 3월 21일
0

[딥다이브]

목록 보기
6/11

전역변수

  • 전역변수는 말 그대로 전역에 선언된 변수이다..

지역변수의 생명주기

  • 보통 지역변수의 생명주기는 함수의 생명주기와 일치한다.
function outerFunction() {
  var outerVariable = "I'm outer variable";

  function innerFunction() {
    var innerVariable = "I'm inner variable";

    console.log(outerVariable); // outerVariable 출력 가능
    console.log(innerVariable); // innerVariable 출력 가능
  }

  innerFunction();
  console.log(outerVariable); // outerVariable 출력 가능
  console.log(innerVariable); // ReferenceError: innerVariable is not defined
}

outerFunction();

outerFunction내에 존재하는 변수 및 함수 => outervariable innerFunction

innerFunction 내에 존재하는 변수 => innerVariable

위 코드를 보면 innerFunction 함수를 outerFunction 내에서 호출하고 있으며 이 때 innerFunction 함수는 스코프체인의 첫 지점이기 때문에 모든 변수를 참조 가능하다. 그리고 outerFunction에서는 innerFunction의 지역변수를 참조하려 하고 있다. 그러나, 앞서 말했다 시피 지역변수의 생명주기는 함수의 생명주기와 일치한다. 그렇기 때문에 참조 에러가 발생한다.

스코프도 마찬가지?

  • 또한 스코프도 마찬가지이다. 누군가 스코프를 참조하고 있으면 스코프는 소멸하지 않고 생존하게 된다.

전역변수의 생명주기

  • 그렇다면 전역변수의 생명주기는 어떻게 되는 것일까?

=> var로 선언한 변수는 전역 객체의 프로퍼티가 된다. 이는 전역객체의 생명주기와 전역 변수의 생명주기가 일치하다는 것을 뜻한다.

깨달은 것

  • 만약 전역으로 선언한 변수가 많다면 어떻게 될까? 특히 또 var로 선언한 변수가 많고 프로젝트 규모가 커진다면 정말 골치 아파질 것 같다.. var로 선언한 변수는 변수명이 동일하다면 암묵적 결합이 일어날 수도 있고 예상치 못한 결과를 초래할 수도 있다. 또 이를 보완한다고 let, const를 사용하여 변수명이 겹치는 불상사를 막았다고 해보자. 개발하는 입장에선 편할 수 있겠지만 실행되는 내내 전역 객체가 종료되기 전까지 전역으로 선언한 변수들은 메모리를 계속 사용하고 있게될 것이다... 시스템 적으로 정말 별로일 것 같다.

느낀 점

var는 쓰지말자.
지역 변수 선언을 생활화 합시다.


블록 레벨 스코프

var의 문제점

  • 또 다룰 부분이 var이다...
var x=1;

if(true){
	var x=10;
}

console.log(x); //10
  • 조건문, 반복문 등 {, } 로 감싸져 있는 것을 블록 레벨 스코프 라고 부른다. var는 함수스코프만 따르기 때문에 위와 같은 코드에서 중복선언으로 인식돼 암묵적 결합이 일어나 재할당이 되어버린다..

let과 const

let x=1;

{
  //TDZ - Temporal Dead Zone
	let x=2;
  	let y=3
}

console.log(x); // 1
console.log(y); //y is not defined
  • var와 다르게 let과 const로 선언한 변수는 함수스코프를 포함한 모든 블록레벨스코프를 따른다. 또한 중복선언이 불가능하며, const로 선언한 변수는 재할당도 불가능하다.

  • 호이스팅이 일어나지 않는 것처럼 보이지만 모두 런타임 이전에 호이스팅이 일어나며 var처럼 메모리공간을 확보하여 undefined로 초기화를 하진 않는다. 런타임 이전에 호이스팅이 일어나면서 자바스크립트 엔진 내에서 존재만 파악한다고 이해하면 쉽다. 또한 변수선언문 이전에 그 변수를 참조하려고 하면 Cannot access before Initialization 이라는 에러가 출력된다. 선언문 전에 참조할 수 없다 라는 에러 자체가 호이스팅이 되었다는 증거이고 이렇게 블록레벨스코프 최상단에선 선언한 지역변수를 참조할 수 없다 이러한 지역을 TDZ(Temporal Dead Zone) 이라고 부른다!

결론

var 다신 보지말자.
재할당이 필요한 경우에만 let을 쓰자.
const 쓰자.

profile
자대고 css 하는 프론트엔드 개발자

0개의 댓글