TIL - Deep dive to 변수

김현재·2021년 10월 12일
0

Javascript 탐구하기

목록 보기
1/1
post-thumbnail

변수 Variable이란

프로그래밍에의 변수는 문자열, 숫자, 객체 등으로 변경할 수 있는 데이터가 담길 수 있는 (빈) 그릇을 의미한다.

변수의 구성

변수는 마치 object처럼 key와 value가 각각 메모리 데이터를 하나씩 차지하고 있는 형태로 구성되어있다.

key(변수명)은 하나의 값을 저장하기 위해 확보한 메모리 공간 자체 또는 그 메모리 공간을 식별하기 위해 붙인 이름을 지칭한다.
변수명이 저장되어있는 메모리에는 변수 이름과 함께 value가 위치해있는 메모리 주소가 기재되어있다.
value(변수값)은 절적한 메모리 위치에 그 값을 보관하고 있다.
변수값은 항상 고정된 자리에 위치해 있으며, 변수명은 그에 대응하는 값이 바뀔때마다 메모리 주소를 바꿔놓는다.

쉽게 현실적 예를 들어서 비유해보면,
약속이 있어 옷을 입으려는데 날이 추워져 원래 입으려던 짧은 원피스 대신 코트와 바지를 입고 나가게 된 상황을 들 수 있다.
여기서 옷을 입는 주체인 나(변수명)는 변하지 않는다.
허나, 내가 입은 옷(변수값)은 원피스에서 코트로 바뀌었다.
원피스는 서랍(메모리주소)에, 코트는 장롱(메모리주소)안에 있었고, 코트를 입으려고 나는 서랍이 아닌 장롱을 열었다.(변수명에 대응하는 value의 메모리 주소값 변경)

즉 정리하면, 변수명과 변수값은 별도로 저장되어 있으며, 변수값의 메모리주소를 변수명과 함께 기재하여 연결시켜놓은 형태이다.
그리고 그 값이 변경되는 경우 새로운 메모리에다가 변경된 값을 저장(절대 덮어쓰지 않는다)해놓고, 새로운 메모리 주소로 변수 데이터를 변경하는데 이를 name binding이라 지칭한다.

?왜 변수값을 변수명이 담긴 메모리에 직접 대입하지 않는 걸까?

  1. 가변적인 변수값의 메모리 용량을 효과적으로 대응하기 위해
    "변수"라는 단어 자체가 주는 느낌처럼, 변수는 값이 일정하지 않고 변하는 형태이다.
    변수 값이 매번 변한다는 것은, 그 변수 값에 대응하는 메모리 용량도 변한다는 것이다. 메모리 용량이 변한다는 것은, 각 변수가 차지하고 있는 메모리의 위치, 크기도 계속 변한다는 것인데, 이렇게 위치를 바꾸다보면 변수명도 건드릴 수 밖에 없다.
    그리고 이러한 메모리 변경이 잦다면 변수명도 그만큼 자주 건드려야되는 거고 이는 변수명과 관련된 오류가 발생할 확률을 높이기에 위험 부담이 크다.
    허나 변수명을 별도로 저장해놓으면 변수값의 크기나 위치가 변해도 변수명은 변하지 않고 고정적으로 존재하기에 보다 안정적인 형태를 유지할 수 있다.

  2. 중복된 데이터를 보다 효율적으로 처리하기 위해
    각 변수가 항상 다른 값을 지니고 있다는 법은 없다. 한 변수에 대한 값으로 사용한 것이 또다른 변수에 대한 값으로 사용될 수 있는데, 똑같은 value인데 일일이 다른 메모리를 차지하게 하는것은 메모리 효율에 좋지 않다.
    허나 변수명과 변수값을 분리해놓으면 공통된 변수값을 가지는 경우 하나의 메모리만 재사용하면 되기 때문에 메모리 효율을 높일 수 있다.

let a = 5; // a의 메모리 주소 : 10001, 5의 메모리 주소 : 50001
let b = 5; // b의 메모리 주소 : 10002, 5의 메모리 주소 : 50001
a = 7; // a의 메모리 주소 : 10001, 7의 메모리 주소 : 50002

💡 재사용하지 않고 방치되는 변수 값들은 어떻게되나요?
불필요한 값들은 garbage collector에 의해 메모리에서 자동 해지된다. 허나, 언제 해지될지는 알 수 없다

Garbage collector) App이 할당한 메모리 공간을 주기적으로 검사하여 더이상 사용되지 않는 메모리를 해제(rebase)하는 기능을 말한다.
더이상 사용되지 않는 메모리는 어떤 식별자도 참조하지 않는 메모리 공간을 의미한다
자바스크립트는 가비지 콜렉터를 내장하고 있는 managed language이다.
managed language) 메모리의 할당 및 해제를 위한 메모리 관리 기능을 언어 차원에서 담당하는 언어. 개발자의 직접적인 메모리 제어를 허용하지 않는다.


변수와 식별자(Identifier)

식별자라는 말은 변수라는 말 만큼 많이 사용되는 말이다.
변수를 좀 더 깊게 들어가기 이전에 식별자를 먼저 이해하고 지나가보자.

식별자는 메모리상에 존재하는 어떤 값을 식별하는데 사용되는 이름, 즉 메모리 주소에 붙인 이름을 의미하는데, 이 이름은 변수명이 될 수도 있으며, 함수명, 클래스명 또한 식별자로서 기능할 수 있다.

이러한 식별자는 모두 실행 컨텍스트*에 등록되어 활용된다.

💡 실행 컨텍스트
자바스크립트 엔진이 소스코드를 평가하고 실행하기 위해 필요한 환경을 제공하고 코드의 실행 결과를 실제로 관리하는 영역. 변수 이름과 값은 실행 컨텍스트 내에 key, value 형태로 저장되어있다.
자바스크립트 엔진은 실행 컨텍스트를 통해 식별자와 scope를 관리한다


Reference Error는 왜 생기나 - 변수와 hoisting

console.log(mention); // undefined로 출력
let mention = "Hello world!";

자바스크립트는 single thread language로 한줄씩 순차적으로 이루어지기에 변수가 선언되기 전에 호출되는 경우 ReferenceError가 나타나야하지만, 실제로 돌려보면 선언 전 호출 시 undefined로 출력된다.
이는 변수 선언이 코드가 한줄씩 실행되는 runtime시점이 아닌, 그 이전단계에서 이루어지기 때문이다.

runtime 이전 시점에서 이루어지는 변수의 선언은 크게 2가지 단계를 거치게 된다.

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

이 이후 runtime시점에 변수에 값을 할당하게 되고, undefined 부분에 변수값을 나타내는 메모리 주소가 할당된다.

이처럼 변수 선언문이 코드의 선두로 끌어 올려진 것 처럼 동작하는 Javascript 고유의 특징을 변수 hoisting이라 한다.



참고자료

  • '코어자바스크립트' 정재남 저, 위키북스
  • '모던 자바스크립트 Deep Dive - 자바스크립트의 기본 개념과 동작 원리' 이웅모 저, 위키북스
profile
쉽게만 살아가면 재미없어 빙고!

0개의 댓글