변수에 대해(1)

Bonggus·2021년 10월 17일
1

자바스크립트

목록 보기
5/23
post-thumbnail

변수?

변수는 프로그래밍 언어에서 데이터를 관리하기 위한 핵심 개념이다. 변수는 하나의 값을 저장하기 위해 확보한 메모리 공간 자체 도는 그 메모리 공간을 식벽하기 위해 붙인 이름을 말한다.

간단히 말하면, 변수는 프로그래밍 언어에서 값을 저장하고, 참조하는 매커니즘이다. 값의 위치를 가리키는 상징적인 이름이다. 변수는 언어의 컴파일러 또는 인터프리터에 의해 값이 저장된 메모리 공간의 주소로 치환되어 실행된다.

따라서 개발자가 직접 메모리 주소를 통해 값을 저장하고 참조할 필요가 없고 변수슬 통해 안전하게 값에 접근 할 수 있다.

변수를 저장하는 것을 할당(대입, 저장)이라하고, 저장된 값을 읽어 들이는 것을 참조(reference)라고 한다.

식별자

변수 이름을 식별자라고도 한다. 식별자는 어떤 값을 구별해서 식별할 수 있는 고유한 이름을 말한다.

값은 메모리 공간에 저장된다. 따라서 식별자는 메모리 공간에 저장되어 있는 어떤 값을 구별해서 식별해 낼 수 있어야 한다.

변수에 저장된 값은, 실제 값이 저장되어 있는 것이 아니라 메모리 주소를 기억하고 있다. 메모리 주소를 통해 값이 저장된 메모리에 접근해서 값을 가져온다. 즉, 식별자는 메모리 주소에 붙은 이름이다.

식별자라는 이름은 변수에만 국한되는 것은 아니다. 변수, 함수, 클래스 등 이름을 '명명'하는 모든 것들이 식별자이다.

변수선언

변수선언은 변수를 생성하는 것을 말한다. 좀 더 자세히 말하면 값을 저장하기 위한 메모리 공간을 확보하고, 변수 이름과 확보된 메모리 공간의 주소를 연결해서 값을 저장할 수 있게 준비하는 것이다. 변수 선언에 의해 확보된 메모리 공간은 확보가 해제 되기 전까지 누구도 확보된 메모리 공간을 사용할 수 없도록 안전하게 보호된다.

변수를 사용하려면 반드시 선언이 필요하다. 변수를 선언할 때는 var, let, const 키워드를 사용한다.

var키워드에는 여러 단점이있는데, 대표적인 것이 블록-레벨-스코프를 지원하지 않고, 함수-레벨-스코프를 지원한다는 것이다. 이로 인해 의도치 않게 전역 변수가 선언되어 부작용이 발생한다.

var

var socre; // 변수 선언

변수 선언 이후, 값을 할당하지 않을 수 있다. 그러면 선언에 의해 변수의 메모리 공간에 undefined가 할당된다. 자바스크립트 엔진은 변수 선언을 2단계에 거쳐 수행한다

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

일반적으로 초기화란 변수가 선언된 이후 최초로 값을 할당하는 것을 말한다. var score;는 선언 단계를 통해 변수 이름 score를 등록하고, 초기화 단계를 통해 score 변수에 암묵적으로 undefined를 할당해 초기화한다.

만약 초기화 단계를 거치지 않으면 확보된 메모리 공간에는 이전에 다른 애플리케이션이 사용했던 값이 남아있을 수 있다. 이러한 값을 쓰레기 값이라 한다. 따라서 메모리 공간을 확보한 다음, 값을 할당하지 않은 상태에서 곧바로 변수 값을 참조하면 쓰레기값이 나올 수 있다. var는 암묵적으로 초기화를 수행하므로 이러한 위험으로부터 안전하다.

변수의 이름을 비롯한 모든 식별자는 실행 컨텍스트에 등록된다. 실행 컨텍스트는 자바스크립트 엔진이 소스코드를 평가하고, 실행하기 위해 필요한 환경을 제공하고 코드의 실행 결과를 실제로 관리하는 영역이다. 자바스크립트 엔진은 실행 컨텍스트를 통해 식별자와 스코프를 관리한다.
변수 이름과 변수 값은 실행 컨텍스트 내에 key/value 형태인 객체로 등록되어 관리된다.

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

console.log(score);

var score;

변수 선언문보다 변수를 참조하는 코드가 앞에 있다. 자바스크립트 코드는 인터프리터에 의해 한 줄씩 순차적으로 질행되므로. console을 실행하고, 변수가 선언된다. 변수가 선언되지 않았기에 에러가 발생할 것 같지만, undefined가 출력된다.

그 이유는 변수 선언이 소스코드가 할 줄씩 순차적으로 실행되는 시점, 즉 런타임이 아니라 그 이전 단계에서 먼저 발생하기 때문이다.

자바스크립트는 런타임에서 실행하기 전에 소스코드의 평가 과정을 거치면서 소스코드를 실행하기 위한 준비를 한다. 소스코드 실행을 위한 준비 단계인 소스코드의 평가 과정에서 자바스크립트 엔진은 변수 선언을 포함한 모든 선언문(변수, 함수 등)을 소스코드에서 찾아내 먼저 실행한다. 그리고 소스코드의 평가 과정이 끝나면 변수 선언을 포함한 모든 선언문을 제외하고, 소스코드를 한줄씩 실행한다.

즉, 자바스크립트 엔진은 변수선언이 소스코드의 어디에 있든 상관없이 다른 코드보다 먼저 실행한다. 따라서 변수선언이 어디에 있든 참조할 수 있다

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

사실 변수 선언뿐 아니라 var, let, const, function, function*, class 키워드를 사용해서 선언하는 모든 식별자는 호이스팅 된다. 모든 선언문은 런타임 이전에 실행되기 때문이다.

값의 할당

var score;
score = 80

or

var score = 80;

위와 아래 모두 선언된 변수에 값이 할당된다. 하지만, 변수 선언은 소스코드가 순차적으로 실행되는 시점인 런타임 이전에 먼저 실행되지만, 할당은 소스코드가 순차적으로 실행되는 시점인 런타임에 실행된다.

console.log(score); //undefined
var score;
score = 80
console.log(score); // 80

자바스크립트가 변수에 값을 할당할 때는 이전값 undefined가 저장되어 있던 메모리 공간을 지우고 그 메모리 공간에 할당 값을 채우는 것이 아니다. 새로운 메모리 공간을 확보하고 그곳에 할당 값 80을 저장한다.

console.log(score);//undefined
score = 80
var score;

console.log(score); // 80

위의 결과도, 사실 같다. 아래 스코어는 80이 찍힌다. 런타임 이전에 score가 먼저 메모리 공간이 할당되기 때문이다.

값의 재할당

var키워드의 경우 선언한 변수값에 새로운 값을 재할당 할 수 있다. 재할당은 현재 변수에 저장된 값을 버리고 새로운 값을 저장하는 것이다. 사실 var키워드로 선언한 변수는 선언과 동시에 undefined가 할당되고, 그 뒤에 값이 들어가는 것이기 때문에 엄밀히 따지면 재할당에 해당한다.

재할당은 변수에 저장된 값을 다른 값이로 변경한다. 그래서 변수라고 한다. 만약 값을 재할당 할 수 없으면? 변경할 수 없다면 그 값을 상수고 한다.

가비지 콜렉터

가비지 콜렉터는 애플리케이션이 할당한 메모리 공간을 주기적으로 검사하여 더 이상 사용하지 않는 메모리를 해제하는 기능(언제 해제될지는 모른다)을 말한다. 더 이상 사용되지 않는 메모리란 간단히 말하자면 어떤 식별자도 참조하지 않는 메모리 공간을 의미한다. 자바스크립트는 가비지 콜렉터를 내장하고 있는 매니지드 언어로 메모리 누수를 방지한다.

자바스크립트는 변수에 값을 재할당 할때마다 이전에 있던 메모리에 값이 덮어씌어지는게 아니다. 새로운 메모리 주소에 값이 할당된다. 떄문에 메모리에 사용하지 않는 값이 계속 쌓이게 되는데, 이러한 사용하지 않는 값을 가비지 콜렉터가 제거 해준다.

매니지드, 언매지니드 언어

프로그래밍 언어는 메모리 관리 방식에 다라 매니지드, 언매니지드 언어로 나눌 수 있다. 매니지드 언어는 개발자가 명시적으로 메모리를 할당하고, 해제하기 위해 malloc(), free()같은 저수준 메모리 제어 기능을 제공한다. 언매니지드 언어는 메모리 제어를 개발자가 주도할 수 잇으므로 개발자의 역량에 따라 최적의 성능을 확보할 수 있지만, 그 반대의 경우 치명적 오류를 발생시킬 수 있다.

자바스크립트 같은 매니지드 언어는 메모리 할당 및 해제를 위한 메모리 관리 기능을 언어 차원에서 담당하고 개발자의 직접적인 메모리 제어를 허용하지 않는다. 즉, 개발자가 명시적으로 메모리를 할당하고 해제할 수 없다. 더 이상 사용하지 않는 메모리의 해제는 가바지 콜렉터가 수행하며, 이 또한 개발자가 관여할 수 없다. 매니지드 언어는 개발자의 역량에 의존하는 부분이 상대적으로 작아져 어느 정도 일정한 생산성을 확보할 수 있다는 장점이 있다. 하지만 메모리 관리 측면에서 어느정도 손실은 감수해야 한다.

출처

  • 모던 자바스크립트 딥다이브
profile
프론트엔드

0개의 댓글