자바스크립트 엔진의 특징으로, 코드가 순차적으로 실행되는
런타임 이전에 먼저 변수선언이 실행
되어ReferenceError
가 일어나지 않고,undefined
의 값이 나오는 현상을hoisting
이라고 한다.(변수 뿐만이 아니라, 함수, 클래스 등모든 식별자들은 호이스팅이 된다.
모든 선언문은런타임 이전 단계에서
먼저 실행되기 때문이다.)
예제 코드 1
console.log(test) // undefined
var test // 변수 선언
다른 인터프리터 언어라면, 인터프리터에 의해 한 줄씩 순차적으로 실행되므로 참조 에러
가 발생해야 하지만 자바스크립트
의 경우에는 undefined
가 나타난다.
예제 코드 2
var a // 변수 선언
a = 100 // 값의 할당
예제 코드 3
var a = 100 // 변수 선언과 값의 할당
2, 3번의 예제는 정확히 동일하게 작동
한다. 자바스크립트 엔진은 변수 선언
과 값의 할당
을 하나의 문으로 단축해도 변수 선언과 값의 할당을 2개의 문으로 나누어서 실행
한다.
하지만 변수 선언과 값의 할당의
실행 시점이 다르다.
변수 선언은런타임 이전
에 먼저 실행되지만, 값의 할당은 코드가 순차적으로 실행되는런타임
에 실행된다.
예제 코드 4
console.log(test) // undefined
var test // 변수 선언
test = 7 // 값의 할당
console.log(test) // 7
이와 같이 런타임 이전에 변수 선언이 먼저 실행되고, 값의 할당은 런타임에 실행되므로 첫 번째 console.log 는 값의 할당보다 앞에 있으므로 값이 재할당 되지 않았고
, 두 번째 console.log 는 값의 할당의 뒤에 있으므로 undefined 였던 초기값이 7의 값으로 재할당
되는 것이다.
이러한 동작원리는 자바스크립트 엔진의 메모리 할당방식에도 깊은 연관이 있다. 첫 변수 선언 때, 초기값 undefined의 값이 메모리공간을 차지한 후,
그 메모리에 값을 재할당 하는 것이 아니라 새로운 메모리 공간에 재할당한다는 점이다.
변수의 값이 매번 바뀔 때마다 새로운 메모리 공간에 값을 넣는 것이다.
그렇다면, 재할당된 변수 이전의 값들 즉, 더 이상 사용되지 않는 값들의 메모리들은 어떻게 되는 것일까? 이는 메모리 공간을 주기적으로 검사
하여 더 이상 사용되지 않는 메모리를 해제하여 메모리 누수
를 방지하는 기능인 garbage collector
로 해결한다. 그래서 자바스크립트는 garbage collector 를 내장하고 있는 managed language
라고 한다.
프로그래밍 언어의 메모리 관리 방식에 따라 두 가지로 나뉠 수 있다. managed language
의 예는 C
C++
과 같은 언어로, 직접 개발자가 메모리 공간을 할당 malloc()
하고, 해제free()
하여 관리하는 방식이다. 이러한 경우 최적화된 메모리 관리
로 좋은 성능을 낼 수 있지만, 그만큼 메모리관리에 주의가 필요
하다.
반대로 unmanaged language
의 예는 C#
Java
JavaScript
과 같은 언어로, 메모리 관리를 언어 자체에서 관리
하고 개발자가 직접 메모리 제어를 허용하지 않는다.
사용하지 않는 메모리는 garbage collector
가 메모리를 해제하고 이 기능 또한 개발자가 제어할 수 없다.
즉, 언제 해제될 지는 알수 없다는 것이다.
장점으로는 메모리 관리에 편리함
이 있지만, 단점으로는 성능적인 측면에서 손실
이 있다는 것이다.(사용하지 않는 메모리가 언제 해제될지 알 수 없기 때문에.)