모던 자바스크립트 Deep Dive : 4장 변수

코코딩딩·2022년 6월 27일
1
post-thumbnail

1. 변수, 식별자, 선언

변수

하나의 값을 저장하기 위해 메모리에서 확보(allocate)한 공간.

식별자(identifier)

메모리 공간을 식별하기 위해서 붙인 변수의 고유한 이름. 식별자는 메모리 주소와 매핑관계를 가진다. 매핑 정보도 메모리에 저장되어야 한다.

변수 선언

식별자와 메모리 주소를 연결(name binding)하여 값을 저장할 수 있게 준비하는 것. 변수 선언에 의해 확보된 메모리 공간은 해제(release)되기 전까지 누구도 해당 공간을 사용할 수 없도록 보호된다.
변수 선언 시 var, const, let 키워드를 사용한다. ES6에서 let과 const가 도입되기 이전까지는 var로 변수를 선언하였다.
변수를 선언만 한 경우 아직 값이 할당되어있지 않는다. 그래서 선언 이후 변수선언에 의해 확보된 메모리가 비어있을 것으로 생각할 수 있으나, 자바스크립트 엔진은 undefined로 할당하여 초기화(initailization)한다.
자바스크립트 엔진은 변수 선언을 다음 두가지 단계에 걸쳐서 수행한다.

  • 선언단계 : 변수 이름을 등록해 자바스크립트 엔진에 변수의 존재를 알린다.
  • 초기화 단계 : 값을 저장하기 위한 메모리 공간을 확보하고 암묵적으로 undifined를 할당해 초기화한다.

var 키워드를 사용한 변수 선언은 선언 단계와 초기화 단계가 동시에 진행된다.
만약 초기화 단계를 거치지 않으면 이전에 다른 어플리케이션이 사용했던 값이 남아 있을수 있다. 이를 쓰레기 값(garbage value)이라 한다. 쓰레기 값 사용의 위험을 제거하기 위해서 자바스크립트의 var 키워드는 초기화를 수행한다.(굳이 undefined가 할당되어야하는 이유가 여기에 있었다. 다른 언어에서는 이를 어떻게 처리하는가?)

변수의 선언 실행 시점과 변수 호이스팅

console.log(score); // undefined
var score; // 변수 선언문

기본적으로 코드는 위에서 한 줄씩 실행되므로 위 코드의 첫 번째 줄에서 ReferenceError가 발생할 것이라 생각이 들지만. undefined를 출력하고 정상적으로 종료된다. 그 이유는 변수 선언이 런타임보다 이전에 먼저 실행되기 때문이다. 자바스크립트 엔진은 런타임에 앞서서 소스코드의 평과 과정을 거치면서 실행을 하기 위한 준비를 한다. 소스코드 평가 과정이 끝나면 비로소 모든 선언문(변수 선언 포함)을 제외하고 소스코드를 한 줄씩 순차적으로 실행한다.

자바스크립트 코드 실행 -> 소스코드 평가(모든 식별자를 선언) -> 선언문을 제외한 나머지 코드를 실행

자바스크립트 엔진은 변수 선언문의 위치와 상관없이 이를 먼저 실행한다. 따라서 변수 선언문의 위치와 상관없이 해당 변수를 참조할 수 있다.(허허;)

이렇게 변수 선언문의 코드가 선두로 끌어올려진 것처럼 동작하는 것을 변수 호이스팅이라 한다. 이는 자바스크립트의 고유한 특징이다.

값의 할당

변수에 값을 할당할 때는 =(대입연산자)를 사용한다.

var socre; // 변수의 선언
score = 120; // 변수에 값을 할당

var score = 120; // 위 두 줄의 축약

선언과 할당을 나눈 코드와 합쳐서 축약한 코드 모두 동일하게 동작한다. 자바스크립트 엔진은 축약하여 선언과 할당을 동시에 하여도 선언문과 할당문으로 나누어 실행한다. 변수의 선언은 런타임 이전에 먼저 실행되지만, 값의 할당은 코드가 순차적으로 실행되는 시점인 런타임에 실행된다.

// undefined. 런타임 시점에 첫 번째로 실행되는 코드. 
//변수 호이스팅으로 인해 undefined가 초기화된 변수를 콘솔에 출력함.
console.log(score); 

// 변수 호이스팅으로 런타임 전에 먼저 선언문이 실행됨.
var score; 

// 런타임 시점에 두 번째로 실행되는 코드. 80이라는 값이 할당 됨.
socre = 80;

//score에 값이 할당되었기에 80 출력. 
console.log(score);

변수의 선언과 동시에 할당을 하여도 자바스크립트 엔진은 선언문과 할당문으로 나눠서 실행한다(변수 호이스팅을 하기 위해서). 변수에 값을 할당할 때는 이전의 값(undefined)가 저장되어있던 메모리 공간을 지우고 그 메모리 공간에 새로 할당할 값을 저장하는게 아니라, 새로운 메모리 공간을 확보하고 그곳에 값을 할당 후 식별자와 식별자와 연결한다는 것을 이해하여야 한다.

변수의 재할당

변수의 재할당이란 이미 값이 들어있는 변수에 새로운 값을 다시 할당하는 것을 의미한다.

var score = 80; // 변수 선언과 동시에 할당.
score = 90; // 새로운 값을 기존 변수에 재할당.

var 키워드로 선언한 변수는 값을 재할당할 수 있다. 재할당이란 기존의 값을 버리고 새로운 값을 할당하는 것이다. 위 코드의 첫번째 보면 선언과 동시에 할당을 한다. 그래서 첫번째 코드는 재할당이 아니라 생각할 수 있다. 하지만 자바스크립트 엔진은 선언문과 할당문은 나눠서 실행하고, 선언 시 undefined로 초기화 하기 때문에, 값을 처음 할당하는 것도 사실 재할당이다.

위 그림과 같이 값을 재할당한다면, 기존에 변수에 담겨있던 메모리 공간을 비우고 새로운 값을 할당하는 것이 아닌, 새로운 메모리 공간을 확보하고 그곳에 값을 할당하여 식별자와 매핑한다. 또한 더이상 식별자와 연결이 되어있지 않는 값은 사용할 수 없게 된다. 이러한 불필요한 값은 가비지 콜렉터에 의해서 메모리에서 자동으로 해제된다.

0개의 댓글