#4. 변수

해피데빙·2022년 7월 7일
0

1. 변수란 무엇인가

모든 애플리케이션은 데이터 입력을 받고 결과를 출력한다
변수는 데이터를 관리하기 위한 핵심 개념이다

변수

  • 하나의 값을 저장하기 위해 확보한 메모리 공간 또는 그 공간을 식별하기 위해 붙인 이름
  • 값의 위치를 가리키는 상징적인 이름
  • 프로그래밍 언어의 컴파일로 또는 인터프리터에 의해 값이 저장된 메모리 공간의 주소로 치환되어 실행된다
  • 변수에 저장된 값의 의미를 파악할 수 있는 이름은 가독성을 높이는 부수적인 효과도 있다
  • 명확한 네이밍은 협업과 품질 향상에 도움을 준다

할당
: 변수에 값을 저장하는 것(대입, 저장)

참조
: 저장된 값을 읽어 들이는 것

Ex. 10 + 20

  • 자바스크립트 엔진 : 자바스크립트를 해석하고 실행한다

JS 엔진은 위 코드를 계산(평가)하려면 리터럴(10,20)과 연산자(+)의 의미를 알고 있어야 하며 이 표현식(10+20)의 의미도 해석(파싱)해야 한다

사람과 달리 컴퓨터는 연산과 기억을 수행하는 부품이 분리되어 있다.

  • CPU : 연산
  • 메모리 : 데이터 기억

메모리란?

  • 데이터를 저장할 수 있는 메모리 셀의 집합체

메모리 셀이란?

  • 메모리 셀 하나의 크기는 1바이트(8비트)

  • 컴퓨터는 메모리 셀의 크기(1바이트) 단위로 데이터를 저장하거나 읽는다

  • 각 셀은 고유의 메모리 주소를 갖는다
    : 메모리 주소는 메모리 공간의 위치를 나타낸다
    : 0부터 시작해서 메모리의 크기만큼 정수로 표현된다
    : 모든 데이터는 이진수로 처리한다

    문제는 위의 계산을 끝낸 값을 어떻게 접근할지다
    30이라는 값을 저장된 메모리 공간에 메모리 주소를 통해 접근하는 것 외에 방법이 없다
    하지만 문제 1) 만약 실수로 운영체제가 사용하고 있는 값을 변경하면 시스템이 멈춘다
    문제 2) 직접 메모리 제어를 할 수 있어도 메모리 주소는 코드가 실행될 때마다 변경된다
    -> 그러므로 실행되기 이전에는 값이 저장된 메모리 주소를 알 수 없다

       이런 문제를 해결하기위해 변수가 생겼다 
       기억하고 싶은 값을 메모리에 저장하고 저장된 값을 읽어들여 재사용하기 위해! 

2. 식별자

식별자란?

  • 어떤 값을 구별해서 식별할 수 있는 고유한 이름
  • 메모리 공간에 저장되어 있는 값을 구별해 낼 수 있어야 하므로 값이 저장되어 있는 메모리 주소를 기억해야 한다
  • 값이 아니라 메모리 주소를 기억하고 있다
  • 네이밍 규칙을 준수해야 한다
  • 선언에 의해 자바스크립트 엔진에 식별자의 존재를 알린다
    ex. 변수, 함수, 클래스

3. 변수 선언

  • 변수를 생성하는 것

    (1)값을 저장하기 위한 메모리 공간을 확보하고
    (2)변수 이름과 확보된 메모리 공간의 주소를 연결해서
    (3)값을 저장할 수 있게 준비하는 것

  • 변수 선언에 의해 확보된 메모리 공간은 확보가 해제되기 전까지는 누구도 확보된 메모리 공간을 사용할 수 없도록 보호되므로 안전하게 사용 가능

  • 선언을 할 때 사용하는 키워드 : var, let, const

cf. var 키워드의 단점

  • 블록 레벨 스코프를 지원하지 않고 함수 레벨 스코프를 지원한다

  • 그러므로 의도치 않게 전역 변수가 선언되어 심각한 부작용이 발생하기도 한다

  • 이를 보완하기 위해 let, const 키워드가 생김

    cf. 키워드
    : 자바스크립트 엔진이 수행할 동작을 규정한 일종의 명령어다
    : 엔진이 키워드를 만나면 자신이 수행해야 할 약속된 동작을 수행한다
    ex. var 키워드를 만나면 자바스크립트 엔진은 뒤에 오는 변수 이름으로 새로운 변수 선언

var 키워드의 경우

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

var 키워드에서 초기화가 선언과 동시에 일어나는 이유?

초기화 단계를 거치지 않으면 확보된 메모리 공간에는 이전에 다른 애플리케이션이 사용했던 값(쓰레기 값)이 남아있을 수 있다. 따라서 메모리 공간을 확보한 다음, 값을 할당하지 않은 상태에서 곧바로 변수 값을 참조하면 쓰레기 값이 나올 수 있다.

cf.undefined는 js에서 제공하는 원시 타입의 값.

변수 이름을 비롯한 모든 식별자는 실행 컨텍스트에 등록된다

실행 컨텍스트란?

자바스크립트 엔진이 소스코드를 평가하기 위해 필요한 환경 제공
자바스크립트 엔진이 소스코드를 실행하기 위해 필요한 환경 제공
코드의 실행 결과를 실제로 관리하는 영역
식별자와 스코프를 관리한다 : { 키(변수 이름) : 값(변수 값) }의 객체로 등록되어 관리

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

ReferenceError

선언하지 않은 식별자에 접근하면 ReferenceError가 발생한다
식별자를 통해 값을 참조하려 했지만 자바스크립트 엔진이 등록된 식별자를 찾을 수 없을 때 발생하는 에러

호이스팅

선언문이 코드의 선두로 끌어 올려진 것처럼 동작하는 자바스크림트 고유의 특징

console.log(score); //undefined (선언 + 초기화가 런타임 전 평가 과정에서 실행)
var score;

undefined가 뜨는 이유?
변수 선언이 소스코드가 한 줄씩 순차적으로 실행되는 시점인 런타임이
이 아니라 그 이전 단계에서 먼저 실행되기 때문이다

런타임 전 먼저 소스코드의 평가 과정을 거치면서 실행하기 위한 준비를 한다
평가 과정 : 자바스크립트 엔진은 모든 선언문을 소스코드에서 찾아내 먼저 실행한다. 평가 과정이 끝나면 모든 선언문을 제외하고 소스코드를 한줄씩 순차적으로 실행한다

5. 값의 할당

ex1.
var score = 80; 

ex2.
var score; //1)선언 + 초기화 : 런타임 이전 평가 과정에서 실행
score=80;  //2)할당 : 런타임에 실행 
  • 변수에 값을 할당할 때는 = 을 이용한다
    좌변의 변수에 우변의 값을 할당한다

  • 위의 두 예제는 동일하게 동작한다.

  • 변수 선언과 값의 할당의 실행시점이 다르다

  • 변수에 값을 할당할 때는 이전 값 undefined가 저장되어 있던 메모리 공간을 지우고 그 메모리 공간에 할당 값 80을 새롭게 저장하는 것이 아니라 새로운 메모리 공간을 확보하고 그 곳에 할당 값 80을 저장한다

console.log(score) //undefined 

score = 80; //런타임 때 재할당됨
var score;  //런타임 이전에 선언 + undefined로 할당

console.log(score) //런타임에서 score=80으로 재할당되어 80 

6. 값의 재할당

재할당이란?
이미 값이 할당되어 있는 변수에 새로운 값을 또다시 할당하는 것을 말한다

엄밀히 말하면 변수에 처음으로 값을 할당하는 것도 재할당
: 선언과 동시에 undefined로 초기화되니까!

처음 값을 할당했을 때와 마찬가지로 이전 값이 저장되어 있던 메모리 공간을 지우고 재할당 값을 넣는 것이 아니라 새로운 메모리 공간을 확보하고 그 메모리 공간에 재할당값을 넣는다

재할당 이후에는 이전의 공간은 어떤 식별자와도 연결되지 않게 된다. 이런 불필요한 값들은 가비지 콜렉터에 의해 메모리에서 자동 해제된다. 단, 메모리에서 언제 해제될지는 예측할 수 없다.

cf. 변수 vs 상수
: 상수는 값을 재할당할 수 없어서 변수에 저장된 값을 변경할 수 없는 것
ex. const

cf. 가비지 콜렉터

  • 앱이 할당한 메모리 공간을 주기적으로 검사해 더 이상 사용하지 않는 메모리를 해제하는 기능
  • 더 이상 사용하지 않는 메모리 공간 : 어떤 식별자도 참조하지 않는 메모리 공간
  • 자바스크립트는 가비지 콜렉터를 내장하고 있는 '매니지드 언어'
  • 메모리 누수를 방지한다

cf. 언매지니드 언어 vs 매니지드 언어
언매니지드 언어 : 명시적으로 메모리를 할당하고 해제하기 위해 malloc()과 free() 같은 저수준 메모리 제어 기능을 제공한다
ex. C 언어

매니지드 언어 : 메모리의 할당 및 해제를 위한 메모리 관리 기능을 언어 차원에서 담당하고 개발자의 직접적인 메모리 제어를 허용하지 않는다
-> 가비지 콜렉터가 알아서 더 이사 ㅇ사용하지 않는 메모리의 해제를 수행한다

profile
노션 : https://garrulous-gander-3f2.notion.site/c488d337791c4c4cb6d93cb9fcc26f17

0개의 댓글