자바스크립트에서의 변수란, 여러 식별자 중에 하나로,
하나의 값을 저장하기 위해 확보한 메모리 공간 자체 또는 그 메모리 공간을 식별하기 위해 붙인 이름이다. (p.36)
컴퓨터는 값을 저장할 때, 메모리를 사용하게 되며, 메모리에는 값이 이진수로 저장되어 있다. 이때 컴퓨터는 값을 구별하기 위해 메모리 주소를 사용한다. 이 메모리 주소는 코드가 실행될 때마다 바뀌게 되는데, 이렇게 변화하는 메모리 주소를 추적하여 기억함으로써, 개발자가 메모리 주소에 직접 접근하지 않고서도 편리하게 값을 참조하거나 생성할 수 있도록 도와주는 것이 식별자이다. 식별자의 종류에는 함수, 클래스 등 여러 가지가 있지만 그 중에서 변수는 단 하나의 값을 식별하기 위한 식별자이다.
자바스크립트에서의 변수 선언이 의미하는 바는,
값이 저장될 메모리 공간을 확보하고, 변수와 확보된 메모리 공간의 주소를 연결(mapping)해서 값을 저장할 수 있게 준비하는 것이다. (p.39)
자바스크립트에서 변수 선언을 하기 위해서는 키워드가 필요한데, 최신 문법인 ES6에서는 var, let, const 를 제공하고 있다. 선언을 위해서는 선언 단계와 초기화 단계를 거쳐야 하는데, var 키워드는 선언 단계와 동시에 초기화 단계가 진행된다.
선언 단계는 자바스크립트 엔진에 변수의 존재를 알리는 단계이며, 초기화 단계는 등록된 변수에 할당할 메모리 공간을 확보하고, undefined 를 할당한다.(p.41)
(선언이라는 말이 중복해서 나와 좀 헷갈릴 수 있다. 선언은 초기화까지 포함된, 말 그대로 변수를 사용할 준비를 모두 마친 상태라고 보면 되고, 선언 단계는 초기화하기 전, 자바스크립트 엔진에 변수의 존재를 알리는 단계라고 보면 될 것 같다.)
var 키워드는 선언 단계와 동시에 초기화 단계가 암묵적으로 실행되므로, 쓰레기값을 참조하게 될 위험으로부터 안전하다는 장점이 있다.
만약 변수를 선언하지 않은 채로 (사실 모든 식별자가 그러하다) 변수에 접근하려 하면, ReferenceError(참조 에러)가 발생한다.
자바스크립트에서의 변수 선언은, 런타임 이전에 소스코드의 평가 과정에서 실행된다. 이처럼
변수 선언문이 코드의 선두로 끌어 올려진 것처럼 동작하는 자바스크립트 고유의 특징을 변수 호이스팅이라 한다.
변수 뿐만 아니라, 키워드를 통해 선언되는 모든 식별자는 호이스팅이 된다는 것은 꼭 기억해야 할 것 같다.
변수 선언과 달리 값의 할당은 런타임에 실행된다. 이는 변수의 선언과 값의 할당을 동시에 하는 경우에도 마찬가지이다. 또, 값을 할당할 경우에는 기존에 있던 초기값을 지우고 그 자리에 새로운 값이 쓰이는 것이 아니라, 새로운 메모리 공간이 할당되고 식별자가 그 새로운 공간을 참고하게 된다. 재할당 역시 마찬가지로, 기존의 값을 지우는 것이 아닌, 새로운 메모리 공간이 확보되는 방식으로 이뤄진다. 이때 값의 할당이나 재할당으로 참조하고 있는 식별자가 모두 없어진 메모리 주소의 값은 가비지 콜렉터의 수집 대상이 되어, 언젠가 메모리에서 해제되게 된다. (자바스크립트는 매니지드 언어로, 메모리 할당 및 해제를 개발자가 직접 제어할 수 없다. 이에 안정적인 개발이 가능하고 일정한 생산성을 보장할 수 있지만, 메모리가 언제 해제될지 정할 수 없고, 그로 인한 약간의 손실을 감수해야 하는 단점이 있다.)
값은 식(표현식)이 평가되어 생성된 결과를 말한다. 평가란 식을 해석해서 값을 생성하거나 참조하는 것을 의미한다.(p.50)
값은, 식을 해석해서 값을 생성하거나 참조해 생성된 결과이다. 이는 내가 기존에 가지고 있던 값의 개념과 달라, 처음에 이해하기 힘들었는데, 내가 생각한 값의 가장 기본적인 형태는 리터럴이었기에 그랬다.
리터럴은 사람이 이해할 수 있는 문자 또는 약속된 기호를 사용해 값을 생성하는 표기법을 말한다.(p.51)
const a = 3;
변수에 값을 할당한다고 했을 때, 쉽게 생각할 수 있는 형태이다.
기존에 가지고 있던 생각: 위 식에서 값은 3인데, 3은 식이 아니라 수이다. 그런데 어떻게 값의 정의가 식을 평가하여 생성한 결과라는 말인가?
내용을 이해한 지금은 이렇게 말할 수 있을 것 같다. 위 코드에 있는 3은 리터럴이다. 즉 a 에 저장될 값 3과는 다른, '표현식'이다. 여기서부터 조금 머리가 아프다. 그럼 표현식이란 무엇일까?
표현식은 값으로 평가될 수 있는 문이다. 즉, 표현식이 평가되면 새로운 값을 생성하거나 기존 값을 참조한다. (p.52)
앞서 본 리터럴이 표현식의 한 종류이다. 즉 리터럴을 해석하면, 새로운 값(3)이 생성되어 변수에 할당되는 것이다. 표현식에는 리터럴외에도 여러 종류가 있다. 수식이나 함수 호출, 식별자등의 조합으로 표현될 수 있다. 무엇이든 그것이 값으로 평가될 수 있기만 하다면, 이는 모두 표현식이라 할 수 있다.
표현식과 함께 등장하는 개념이 문이라는 개념이다. 명령문할 때의 문(statement)인데,
문은 프로그램을 구성하는 기본 단위이자 최소 실행 단위다. (p.54)
문은 토큰으로 이루어져 있다.(국어 문법으로 치면, 토큰은 형태소, 문은 문장인 것 같다.)
토큰이란 문법적인 의미를 가지며, 문법적으로 더 이상 나눌 수 없는 코드의 기본 요소를 의미한다. (p.54)
문 하나 하나가 모여 집합을 이룬 것이 프로그램이다. 즉 문은 프로그램을 만들기 위한 최소의 단위라고 보면 된다.
표현식은 그 자체로 문이 될 수 있다. 예를 들어 할당문의 경우, x = 1 + 2 에서 볼 수 있듯, 식을 해석하여 값을 생성해 할당하고 있으므로, 그 자체가 표현식이며, 프로그램을 실행시킬 수 있는 최소 단위이므로, 문이자 표현식이다.
반면 표현식이 아닌 문도 있다. 예를 들어 선언문의 경우, 생성되거나 참조되는 값이 없으므로, 식을 평가한다고 볼 수 없다. 따라서 이는 문이기는 하지만 표현식은 아니다.
이 글은 모던 자바스크립트 Deep Dive 를 읽고, 이해하여 내 나름대로 정리를 해 본 글이다. 정의와 같이 어쩔 수 없이 책의 내용을 그대로 빌려와야 하는 경우, 인용 블록을 이용하였다. 쉬운 책은 아니지만, 내용을 계속해서 곱씹다 보니 그렇게 어려운 책도 아니라는 생각이 들었다. 앞으로 주말마다 한 장에서 두 장씩 꾸준히 읽고 벨로그에 정리하여 깊이 있는 개발자가 되기 위해 노력해야겠다! 긴 글 읽어주셔서 감사합니다 :)
"값을 할당할 경우에는 기존에 있던 초기값을 지우고 그 자리에 새로운 값이 쓰이는 것이 아니라, 새로운 메모리 공간이 할당되고 식별자가 그 새로운 공간을 참고하게 된다." 이 부분이 인상 깊네요! 저는 그냥 새로운 값이 덮어씌워진다고 생각했었거든요....! 그리고 리터럴 관련된 부분은 정말 흥미롭네요! 한 번도 a=3에서 3을 식으로 본 적이 없었는데 식의 한 종류라니 이건 제법 충격이에요! 사실 그냥 몰라도 개발할 수 있다고 간과하고 넘어갈 수도 있는데 이런 부분들이 모여서 진짜 실력이 되는 것 같아요! 수고하셨습니다:)
정말 까르꼼하게 정리해주셨는데요?? 너무 읽기 좋았습니다 ~ 한 가지 궁금한 게 있어 적어보았는데욥!! 호이스팅이 "변수 선언문이 코드의 선두로 끌어 올려진 것처럼 동작하는 자바스크립트 고유의 특징" 이잖아요! 그럼 선두로 끌어올려진 것 처럼 동작하는 거면 실제로 선두로 끌어 올려지진 않은 건가요?? 호이스팅이 아직두 어렵네욥... 도와줘요 자스요정~