컴퓨터는 메모리를 사용해 데이터를 기억한다.
메모리는 데이터를 저장할 수 있는 메모리 셀의 집합체이다.
메모리 셀 하나의 크기: 1바이트(8비트)
컴퓨터는 메모리 셀의 크기, 즉 1바이트 단위로 데이터를 저장하거나 읽어들인다.
각 셀은 고유의 메모리 주소를 갖는다.
메모리 주소는 메모리 공간의 위치를 나타내며, 0부터 시작해서 메모리의 크기만큼 정수로 표현된다.
자바스크립트는 개발자의 직접적인 메모리 제어를 허용하지 않는다.
🧐 Why?
- 메모리 주소를 통해 값에 직접 접근하는 것은 치명적 오류를 발생시킬 가능성이 높은 매우 위험한 일이다.
- 실수로 운영체제가 사용하고 있는 값을 변경하면 시스템을 멈추게 하는 치명적인 오류가 발생할 수도 있다.
- 메모리 주소는 코드가 실행될 때 메모리의 상황에 따라 임의로 결정된다.
동일한 컴퓨터에서 동일한 코드를 실행해도 코드가 실행될 때마다 값이 저장될 메모리 주소는 변경된다.
따라서, 메모리 주소를 통해 값에 직접 접근하려는 시도는 올바른 방법이 아니다.
variable
하나의 값을 저장하기 위해 확보한 메모리 공간 자체 또는 그 메모리 공간을 식별하기 위해 붙인 이름을 말한다.
변수는 프로그래밍 언어의 컴파일러 또는 인터프리터에 의해 값이 저장된 메모리 공간의 주소로 치환되어 실행된다.
개념 | 설명 |
---|---|
변수 이름 = 변수명 | 메모리 공간에 저장된 값을 식별할 수 있는 고유한 이름 |
변수 값 | 변수에 저장된 값 |
assignment 할당 = 대입 = 저장 | 변수에 값을 저장하는 것 |
reference 참조 | 변수에 저장된 값을 읽어 들이는 것 |
identifier
메모리 상에 존재하는 어떤 값을 식별할 수 있는 이름은 모두 식별자라고 부른다.
(변수, 함수, 클래스 등의 이름은 모두 식별자다.)
식별자는 값이 저장되어 있는 메모리 주소와 매핑 관계를 맺으며, 이 매핑 정보도 메모리에 저장된다.
값이 아니라 메모리 주소를 기억하고 있다.
식별자 네이밍 규칙
- 특수문자를 제외한 문자, 숫자, _, $를 포함할 수 있다.
- 숫자로 시작하는 것은 허용하지 않는다.
- ES5부터 유니코드 문자를 허용하지만 권장하지 않는다.
네이밍 컨벤션
- 하나 이상의 영어 단어로 구성된 식별자를 만들 때 가독성 좋게 단어를 한눈에 구분하기 위해 규정한 명명 규칙이다.
- 카멜 케이스: 변수, 함수에 사용
camelCase
- 파스칼 케이스: 생성자 함수, 클래스 이름에 사용
PascalCase
variable declaration
변수를 사용하려면 반드시 선언이 필요하다!
선언하지 않은 식별자에 접근하면 ReferenceError(참조 에러)가 발생한다.
변수 선언은 변수를 생성하는 것을 말한다.
값을 저장하기 위한 메모리 공간을 확보(allocate)하고 변수 이름과 확보된 메모리 공간의 주소를 연결(name binding)해서 값을 저장할 수 있게 준비하는 것이다.
변수 선언에 의해 확보된 메모리 공간은 확보가 해제(release)되기 전까지는 누구도 확보된 메모리 공간을 사용할 수 없도록 보호되므로 안전하게 사용할 수 있다.
값을 저장하기 위한 메모리 공간을 확보하고 암묵적으로 undefined를 할당해 초기화한다.
초기화 단계를 거치지 않으면 확보된 메모리 공간에는 이전에 다른 애플리케이션이 사용했던 값이 남아있을 수 있고, 이러한 값을 쓰레기 값이라 한다.
var 키워드는 선언 단계와 초기화 단계가 동시에 진행되어 (암묵적으로 초기화를 수행) 이러한 위험(쓰레기 값으로부터 안전하다.
값의 재할당
- 변수에 값을 재할당하면 새로운 메모리 공간을 확보하고 그 메모리 공간에 값을 저장한다.
- 이전에 사용하던 메모리 공간에 있는 불필요한 값들은 가비지 콜렉터에 의해 메모리에서 자동 해제되어 메모리 누수를 방지한다.
(언제 해제될지는 모름)
excution context
변수 이름을 비롯한 모든 식별자는 실행 컨텍스트에 등록된다.
실행 컨텍스트는 자바스크립트 엔진이 소스코드를 평가하고 실행하기 위해 필요한 환경을 제공하고 코드의 실행 결과를 실제로 관리하는 영역이다.
자바스크립트 엔진은 실행 컨텍스트를 통해 식별자와 스코프를 관리한다.
변수 이름과 변수 값은 실행 컨텍스트 내에 키/값 형식인 객체로 등록되어 관리된다.
자바스크립트는 변수를 선언하면 암묵적으로 정의가 이뤄지기 때문에 선언과 정의의 구분이 모호하다.
ECMAScript 사양에서 변수는 '선언한다'라고 표현하고, 함수는 '정의한다'라고 표현한다.
C언어
- C언어에서 선언과 정의는 "실제로 메모리 주소를 할당하는가"로 구분한다.
- 선언: 컴파일러에게 식별자의 존재만 알리는 것
- 정의: 컴파일러가 변수를 생성해서 식별자와 메모리 주소가 연결된 것
자바스크립트 코드는 인터프리터에 의해 한 줄씩 순차적으로 실행된다.
하지만 변수 선언은 런타임(소스코드가 한 줄씩 순차적으로 실행되는 시점)이 아닌 그 이전 단계에서 먼저 실행된다!!!
소스코드를 실행하기에 앞서 먼저 소스코드의 평가 과정을 거치면서 소스코드를 실행하기 위한 준비를 한다.
이때 모든 선언문(변수 선언문, 함수 선언문 등)을 소스코드에서 찾아내 먼저 실행한다.
소스코드의 평가 과정이 끝나고 나서 선언문을 제외한 소스코드를 한 줄씩 순차적으로 실행한다.
variable hoisting
변수 선언문이 코드의 선두로 끌어 올려진 것처럼 동작하는 자바스크림트 고유의 특징을 변수 호이스팅이라 한다.
변수 선언뿐 아니라 var, let, const, function, function*, class
키워드를 사용해서 선언하는 모든 식별자(변수, 함수, 클래스 등)는 호이스팅된다.
자바스크립트 엔진은 변수 선언과 값의 할당을 2개의 문으로 나누어 각각 다른 시점에 실행한다.
변수 선언은 소스코드가 순차적으로 실행되는 시점인 런타임 이전에 먼저 실행되지만,
값의 할당은 소스코드가 순차적으로 실행되는 시점인 런타임에 실행된다.