JavaScript

[JavaScript] 변수 - 변수 호이스팅, 값의 할당, 값의 재할당, 식별자 네이밍 규칙

김나나_ 2023. 11. 1. 18:43

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

console.log(score); // undefined

var score; // 변수 선언문

 

위의 코드를 실행하면 참조 오류가 발생할 것 같지만, 참조 에러가 발생하지 않고 undefined가 출력된다.

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

 

자바스크립트 엔진은 소스코드를 한 줄씩 순차적으로 실행하기에 앞서 먼저 소스코드의 평가 과정을 거치면서 소스코드를 실행하기 위한 준비를 한다.

(소스코드 평가 과정 -> 소스코드 실행 순)

소스코드 평가 과정에서 자바스크립트 엔진은 모든 선언문(변수 선언문, 함수 선언문 등)을 소스코드에서 찾아내 먼저 실행한다. 그리고 소스코드의 평가 과정이 끝나면 모든 선언문을 제외하고 소스코드를 한 줄씩 순차적으로 실행한다.

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

 

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

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

 

정리하자면,

  • 모든 선언문은 런타임 이전 단계에서 먼저 실행된다.
  • 선언하는 모든 식별자(변수, 함수, 클래스 등)는 호이스팅된다.

 

값의 할당

변수에 값을 할당(assignment)할 때는 할당 연산자 '=' 를 사용한다.

 

// 1) 선언과 할당을 나눔
var score; // 변수 선언
score = 50; // 값의 할당

// 2) 단축 표현
var age = 25; // 변수 선언과 값의 할당(하나의 문으로 단축 표현)

 

변수 선언과 값의 할당을 2개의 문으로 나누어 표현한 코드 1)와 하나의 문으로 단축표현한 코드 2)는 정확히 동일하게 동작한다.

자바스크립트 엔진은 변수 선언과 값의 할당을 하나의 문으로 단축 표현해도 변수 선언과 값의 할당을 2가지 문으로 나누어 각각 실행한다.

  • 변수 선언: 런타임 이전에 실행
  • 값의 할당: 런타임에 실행

변수 선언과 할당을 하나의 문장으로 단축 표현해도 자바스크립트 엔진은 변수 선언과 할당을 2개의 문으로 나누어 실행하므로 변수에 undefined가 할당되어 초기화되는 것은 변함없다.

 

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

 

 

값의 재할당

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

 

var score = 50; // 변수 선언과 값의 할당
score = 70; // 값의 재할당

 

변수에 값을 재할당하면 score 변수의 값은 이전 값 50에서 재할당 한 값 70으로 변경된다. 처음 값을 할당했을 때와 마찬가지로 이전 값 50이 저장되어 있던 메모리 공간을 지우고 그 메모리 공간에 재할당 값 70을 새롭게 저장하는 것이 아니라 새로운 메모리 공간을 확보하고 그 메모리 공간에 숫자 값 70을 저장한다.

 

그러면 자바스크립트 언어에 의해 암묵적으로 초기화된 undfined 를 저장하고 있던 메모리 공간과, 50을 저장하고 있던 메모리 공간은 어떻게 될까? undfined 와 50은 식별자와 연결되어 있지 않다. 아무도 사용하지 않아 불필요하게 되었다.

이러한 불필요한 값들은 가비지 콜렉터에 의해 메모리에서 자동 해제 된다. (메모리에서 언제 해제될지는 예측할 수 없다)

 

* 가비지 콜렉터(garbage collector)

가비지 콜렉터는 애플리케이션이 할당(allocate)한 메모리 공간을 주기적으로 검사하여 더 이상 사용되지 않는 메모리를 해제(release)하는 기능을 말한다. 더 이상 사용되지 않는 메모리어떤 식별자도 참조하지 않는 메모리 공간을 의미한다.

자바스크립트는 가비지 콜렉터를 내장하고 있는 매니지드 언어이다. 가비지 콜렉터를 통해 메모리 누수(memory leak)를 방지한다.

 

* 언매니지드 언어(unmanaged language)와 매니지드 언어(managed language)

프로그래밍 언어는 '메모리 관리 방식'에 따라 언매니지드 언어와 매니지드 언어로 분류할 수 있다.

  • 언매니지드 언어: C 언어와 같은 언매니지드 언어는 메모리 제어를 개발자가 주도할 수 있으므로 개발자의 역량에 따라 최적의 성능을 확보할 수 있지만 그 반대의 경우 치명적 오류를 생산할 가능성도 있다.
  • 매니지드 언어: 자바스크립트 같은 매니지드 언어는 메모리의 할당 및 해제를 위한 메모리 관리 기능을 언어 차원에서 담당하고 개발자의 직접적인 메모리 제어를 허용하지 않는다. 더 이상 사용하지 않는 메모리의 해제는 가비지 콜렉터가 수행하며, 이 또한 개발자가 관여할 수 없다. 
    => 어느 정도 일정한 생산성은 확보 할 수 있다는 장점이 있지만 성능 면에서는 어느 정도의 손실을 감수해야 한다.

 

식별자 네이밍 규칙

  • 식별자(indenfier): 어떤 값을 구별해서 식별해낼 수 있는 고유한 이름

 

* 식별자의 네이밍 규칙

  1. 식별자는 특수문자를 제외한 문자, 숫자, 언더스코어(_), 달러 기호($)를 포함할 수 있다.
  2. 단, 식별자는 특수문자를 제외한 문자, 언더스코어(_), 달러 기호($)로 시작해야 한다. 숫자로 시작할 수 없다.
  3. 예약어는 식별자로 사용할 수 없다.

출처: https://velog.io/@hadam/JS-%EC%8B%9D%EB%B3%84%EC%9E%90-%EB%84%A4%EC%9D%B4%EB%B0%8D-%EA%B7%9C%EC%B9%99

* 식별자로 사용 가능하나 strict mode 에서는 사용 불가

 

ES5부터 식별자를 유니코드 문자를 허용 => 한글, 일본어도 식별자로 사용가능 (하지만 권장하지 않는다)

자바스크립트는 대소문자를 구별한다.

좋은 변수 이름은 코드의 가독성을 높이므로 변수의 목적을 알아볼 수 있도록 네이밍하는 것이 중요하다.

 

 

* 네이밍 컨벤션(naming convention)

하나 이상의 영어 단어로 구성된 식별자를 만들 때 가독성 좋게 단어를 한눈에 구분하기 위해 규정한 명명 규칙이다.

 

// 1. 카멜케이스(camelCase) - 변수, 함수의 이름에 사용
var firstName;

// 2. 스네이크 케이스(snake_case)
var first_name;

// 3. 파스칼 케이스(PascalCase) - 생성자 함수, 클래스의 이름에 사용
var FirstName;

// 4. 헝가리언 케이스(typeHungarianCase)
var strFirstName; // type + indentifier
var $elem = document.getElementById('myId'); // DOM 노드
var observable$ = fromEvent(document, 'click'); // RxJS 옵저버블

 

 

퀴즈

- 변수 선언은 런타임에 실행된다. (O, X)

더보기

정답: X

 

자바스크립트 엔진은 소스코드를 한 줄씩 순차적으로 실행하기에 앞서 먼저 소스코드의 평가 과정을 거치면서 소스코드를 실행하기 위한 준비를 한다.

(소스코드 평가 과정 -> 소스코드 실행 순)

소스코드 평가 과정에서 자바스크립트 엔진은 모든 선언문(변수 선언문, 함수 선언문 등)을 소스코드에서 찾아내 먼저 실행한다. 그리고 소스코드의 평가 과정이 끝나면 모든 선언문을 제외하고 소스코드를 한 줄씩 순차적으로 실행한다.

 

=> 모든 선언문은 런타임 이전에 실행된다.

 

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

더보기

정답: 호이스팅

 

- 변수에 값을 할당할 때는 이전 값 undefined(초기화 값)가 저장되어 있던 공간을 지우고 그 메모리 공간에 새로운 할당 값을 새롭게 저장하는 것이 아니라 새로운 메모리 공간을 확보하고 그곳에 할당 값을 저장한다. (O, X)

더보기

정답: O

 

- (                     )는 애플리케이션이 할당(allocate)한 메모리 공간을 주기적으로 검사하여 더 이상 사용되지 않는 메모리를 해제(release)하는 기능을 말한다. 더 이상 사용되지 않는 메모리란 어떤 식별자도 참조하지 않는 메모리 공간을 의미한다.

더보기

정답: 가비지 콜렉터(garbage collector)

 

가비지 콜렉터를 통해 메모리 누수(memory leak)를 방지한다.

 

- 자바스크립트는 (언매니지드 언어/매니지드 언어) 이다.

더보기

정답: 매니지드 언어

 

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

 

- 자바스크립트에서 변수, 함수명에 사용하는 네이밍 규칙은?

더보기

정답: 카멜 케이스(camelCase)

 

- 자바스크립트에서 생성자 함수, 클래스에 사용하는 네이밍 규칙은?

더보기

정답: 파스칼 케이스(PascalCase)