[JavaScript] 변수(var)

김희윤·2023년 3월 31일
0

모던 자바스크립트 Deep Dive의 4장 내용을 정리한 글입니다.

변수와 메모리 공간

변수는 하나의 값을 저장하기 위해 확보한 메모리 공간의 식별자이다.

CPU의 연산으로 생성된 값(ex: 1+1)은 메모리에 저장되며, 각 메모리 공간마다 고유의 메모리 주소를 가진다. 그러나 개발자가 직접 메모리 주소를 이용해 해당하는 값에 접근하는 것은 위험할 수 있다. 왜냐하면 실수로 다른 메모리 주소에 접근했다가 운영체제가 사용하고 있는 메모리를 제어해 치명적인 오류를 발생할 수 있기 때문이다.

이러한 문제를 해결하기 위해 자바스크립트(와 통상적인 거의 모든 프로그래밍 언어)에서는 메모리 주소를 저장하는 변수 개념을 도입했다. 변수는 고유의 자연어로 된 변수 이름을 이용해 사람이 메모리 주소를 대체하여 메모리에 저장된 값을 쉽고 안전하게 접근할 수 있게 한다.

식별자 는 어떤 값을 구별해서 식별할 수 있는 고유의 이름을 말한다. 변수 이름 또한 식별자이며, 함수,클래스 등의 이름도 모두 식별자라고 부른다. 우리는 식별자(변수 이름)을 통해 변수가 저장하고 있는(Computer Science에서는 참조라는 용어로 표현한다) 메모리 주소를 통해 해당 메모리 공간이 저장하고 있는 값에 접근할 수 있다.

변수를 이용하기 위해서는 변수를 선언해야 한다. 변수를 선언하면 값을 저장하기 위한 메모리 공간이 확보되며, 변수 이름과 확보된 메모리 공간의 주소를 연결한다. 자바스크립트에서 변수를 선언하는 키워드는 var,let,const이며, 모던 자바스크립트 Deep Dive 4장에서는 var에 대한 설명만 하고 있다.

var로 변수를 선언하는 경우, 자바스크립트 엔진은 변수 선언을 2단계에 겅쳐 수행한다.

  • 선언 단계
    변수 이름을 등록해서 자바스크립트 엔진에 변수의 존재를 알린다.
    => 자바스크립트에서 모든 식별자는 실행 컨텍스트에 등록된다.
  • 초기화 단계
    값을 저장하기 위한 메모리 공간을 확보하고 암묵적으로undefined를 할당해 초기화한다.

일반적으로 초기화란 변수가 선언된 이후 최초로 값을 할당하는 것을 말한다. var 키워드로 선언한 경우 변수 선언 시 값을 할당하지 않아도 undefined로 초기화된다.

변수 이용의 필요조건은 변수 선언이다. 만약 선언되지 않은 변수를 사용한다면
참조 에러가 발생한다.

변수 호이스팅

console.log(greet);
var greet = "hi";

위 코드의 실행결과는 참조 에러가 아닌 undefined이다. 그 이유는 자바스크립트 엔진은 변수의 선언을 런타임이 아닌 그 이전 단계(분석단계)에서 수행하기 때문이다. 자바스크립트 엔진은 코드를 실행하기 이전에, 전체 코드를 훑으며 모든 선언문(변수 선언문, 함수 선언문 등)을 먼저 실행한다. 이러한 평가 단계가 끝나면 모든 선언문을 제외하고 소스코드를 한 줄씩 순차적으로 실행한다.

위 코드에서 변수의 선언과 값의 할당이 동시에 이루어지고 있지만, 자바스크립트 엔진은 해당 코드를 선언과 할당으로 분리하고, 분석 단계에서는 오직 변수 선언만 실행한다. var 키워드로 선언된 변수는 선언과 동시에 undefined로 초기화되기 때문에 콘솔 출력 결과가 undefined인 것이다.

이렇게 변수 선언문이 코드의 선두로 끌어 올려진 것처럼 동작하는 자바스크립트이 특징을 변수 호이스팅이라고 한다. var,let,const,function,class등의 모든 선언문은 모두 호이스팅 된다. 모든 선언문은 런타임 이전 분석 단계에서 먼저 실행되기 때문이다.

값의 할당은 변수 선언과 분리되어 런타임에 실행된다. var키워드로 선언된 변수에 값을 할당할 경우 변수 초기화로 undefined를 저장하고 있던 메모리가 아닌 다른 메모리 공간을 확보해 새로운 할당 값을 저장한다. 변수 새로운 값이 할당된 메모리 공간을 참조하게 된다(=새로운 메모리 공간의 주소를 저장한다)

더이상 참조받지 않은 메모리 공간은 자바스크립트 엔진의 가비지 컬렉터가 메모리 누수를 방지하기 위해 해제한다.

const 키워드를 사용하면 변수에 값을 재할당할 수 없으며, 이러한 특징을 가진 변수를 상수라고 부른다.

식별자 네이밍 규칙

  • 식별자는 문자,숫자,_,$ 만 사용가능
  • 숫자로 시작할 수 없음
  • 예약어 사용 불가

자바스크립트 개발자들이 사용하는 네이밍 컨벤션은 카멜 케이스와 스네이크 케이스이다.

정리

아, 100 이라는 값을 score이라는 이름으로 메모리에 저장하고 싶네

1 console.log(score)
2 score = 100;
3 var score;
4 console.log(score);

자바스크립트 엔진: 전체 소스코드를 실행하기 전에, 선언문을 찾아내자.

아, 3라인에서 var로 선언된 score 변수가 존재하구나, score라는 식별자는 실행 컨텍스트라는 곳에 저장하자. 그리고 시간이 없으니 바로 메모리 공간을 확보하고, 그곳에 undefined를 저장하고, 해당 메모리 공간과 식별자 score를 연결하기 위해 score변수에 해당 메모리 공간의 주소를 저장하자.

자 이제 선언문을 제외한 전체 소스코를 실행해 보자꾸나.

  • 1라인에서 score식별자를 통해 값을 호출하고 있구나. 변수에는 undefined가 저장된 메모리 공간의 주소를 저장하고 있네, undefined를 출력하자.

  • 2라인에서 score식별자를 통해 값을 할당하고 있구나. 새로운 메모릭 공간을 확보하고 그곳에 100을 저장한 뒤, 해당 메모리 공간과 식별자 score를 연결하기 위해 score변수에는 100이 저장된 새로운 메모리 공간의 주소를 저장하자.

  • 3라인은 선언문이므로 이미 분석 단계에서 실행했으니 건너뛰자

  • 4라인에서 score 식별자로 값을 호출하고 있구나, score변수에는 100이 저장된 메모리 공간의 주소를 저장하고 있으므로, 100을 출력하자.

profile
탑 개발자를 향해 오늘도 정진한다.

0개의 댓글