새소식

FE/JavaScript

[Javascript] 변수

  • -

1. 변수란 무엇인가? 왜 필요한가?

변수

하나의 값을 저장하기 위해 확보한 메모리 공간 자체 또는 그 메모리 공간을 식별하기 위해 붙인 이름

 

변수가 필요한 이유

기억하고 싶은 값을 메모리에 저장하고, 저장된 값을 읽어들여 재사용할 수 있기 때문에 필요하다.

 

  • 변수가 없다면, 이전에 실행한 연산 결과를 재사용하고 싶을 때, 메모리주소를 통해 연산 결과가 저장된 메모리공간에 직접 접근해야함 ->  매우 위험
  • 변수를 통해, 개발자가 직접 메모리 주소를 통해 값을 저장하고 참조할 필요가 없고 변수를 통해 안전하게 값에 접근할 수 있다.

 

2. 식별자

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

  • 식별자는 어떤 값이 저장되어있는 메모리주소를 기억(저장)한다.
  • 값이 아니라, '메모리 주소'를 기억하고 있다.
    • 즉, 식별자는 메모리 주소에 붙인 이름이라고 할 수 있다.
  • ex) 변수, 함수, 클래스 등의 이름
  • 식별자는 네이밍 규칙을 준수해야하며, '선언'에 의해 자바스크립트 엔진에 식별자의 존재를 알린다.

 

 

3. 변수 선언

변수 선언 == 변수를 생성하는 것. 변수를 사용하려면 반드시 선언이 필요하다.

  • 값을 저장하기 위한 메모리공간을 확보하고, 변수 이름과 확보된 메모리 공간의 주소를 연결해서 값을 저장할 수 있게 준비하는 것.
  • 변수 선언에 의해 확보된 메모리 공간 -> 확보가 해제(release)되기 전까지 누구도 확보된 메모리공간을 사용할 수 없도록 보호된다.
  • var,let,const 키워드를 사용해 변수를 선언한다.
    • ES6부터 let,const키워드가 도입됨( 이전에는 var가 변수 선언 위한 유일한 키워드였음)

 

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

다음의 코드를 보자

console.log(score) //undefined

var score;

 

 

변수 선언문보다 변수를 참조하는 코드가 앞에 있다. 자바스크립트 코드는 인터프리터에 의해 한 줄씩 순차적으로 실행되므로, console.log(score)가 실행되는 시점에서는 아직 score변수의 선언이 실행되지 않았으므로 참조 에러(Reference Error)가 발생할 것으로 보인다.

하지만, 참조 에러가 발생하지 않고 undefined가 출력된다. => 이유가 뭘까?

 

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

  • JS엔진은 소스코드를 한줄씩 순차적으로 실행하기에 앞서, 소스코드의 평가과정을 거치면서, 소스코드를 실행하기 위한 준비를 한다.
  • 이 때, JS엔진은 변수 선언을 포함한 모든 선언문(변수 선언문, 함수 선언문 등)을 소스코드에서 찾아서 먼저 실행한다.
  • 이 후, 비로소 소스코드를 한 줄씩 순차적으로 실행한다

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

 

즉, 변수 호이스팅에 따라 모든 선언문은 런타임 이전 단계에서 먼저 실행된다

 

5. 값의 할당

 

아래 두 코드를 비교해보자

 

1) 

var score;

score = 80;

 

2)

var score = 80;

 

위 두 코드는 정확히 동일하게 동작한다. 그러나 주의할 점은 변수 선언과 할당의 실행 시점이 다르다는 것이다.

  • 변수 선언 :  소스코드가 순차적으로 실행되는 시점인 런타임 이전에 먼저 실행
  • 값의 할당 : 소스코드가 순차적으로 실행되는 시점인 런타임에 실행

즉, 2)코드와 같이 변수의 선언과 값의 할당을 하나의 문장으로 단축 표현해도, 자바스크립트 엔진은 변수와 선언과 값의 할당을 2개의 문으로 나누어 가각 실행한다.

 

console.log(score) //undefined

var score = 80; //변수 선언과 값의 할당

console.log(score) //80

 

변수에 값을 할당할 때는

  • 이전 값 undefined가 저장되어있던 메모리 공간을 지우고, 그 메모리 공간에 할당 값 80을 새롭게 저장한다 (X)
  • 새로운 메모리 공간을 확보하고 그곳에 할당값 80을 지정한다.(O)

 

6. 값의 재할당

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

var score = 80;
score = 90

 

 

변수에 값을 재할당할 때는

  • 이전 값 80이 저장되어있던 메모리 공간을 지우고, 그 메모리 공간에 할당 값 90을 새롭게 저장한다 (X)
  • 새로운 메모리 공간을 확보하고 그곳에 재할당값 90을 지정한다.(O)

=> 즉, score변수의 이전 값인 undefined와 80은 어떤 식별자와도 연결되어 있지 않다 == undefined와 80이 더 이상 필요하지 않다

=> 이런 불필요한 값들은 *가비지 콜렉터 에 의해 메모리에서 자동 해제된다 ( 언제 해제될지는 예측 X)

 

 

*가비지 콜렉터

- 애플리케이션이 할당한 메모리 공간을 주기적으로 검사하여 더 이상 사용되지 않는 메모리(어떤 식별자도 참조하지 않는 메모리 공간)를 해제하는 기능 - JS는 가비지 콜렉터를 내장하고 있는 *매니지드 언어로서, 가비지 콜렉터를 통해 메모리 누수를 방지

 

* 언매니지드 언어 vs 매니지드 언어

-언매니지드 언어 : C언어와 같은 언매니지드 언어는 개발자가 명시적으로 메모리를 할당하고 해제하기 위해 malloc()과 free() 같은 low-level 메모리 제어 기능을 제공한다. -> 메모리 제어를 개발자가 주도할 수 있으므로, 개발자의 역량에 따라 최적의 성능을 확보할 수 있지만, 그 반대의 경우 치명적인 오류를 생산할 수 있음

 

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

 

 

Reference

https://g.co/kgs/K7K89Lj

 

 

Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.