모던 자바스크립트 딥다이브 책의 내용을 기반으로 작성하였습니다.🌿
컴퓨터는 CPU를 사용해 연산하고, 메모리를 사용해 데이터를 기억한다.
메모리는 데이터를 저장할 수 있는 메모리 셀의 집합체이며, 메모리 셀 하나의 크기는 1바이트(8비트) 이다.
컴퓨터는 1바이트 단위로 데이터를 저장하거나 읽어들인다.
각 셀은 고유의 메모리 주소를 갖는다. 메모리 주소는 메모리 공간의 위치를 나타내며, 0부터 메모리 크기만큼 정수로 표현된다.(0x00000000 ~ 0xFFFFFFFF)
또한, 컴퓨터는 모든 데이터를 2진수로 처리한다. 메모리에 저장되는 데이터는 데이터의 종류와 상관없이 모두 2진수로 저장된다.
10 + 20
이라는 식이 있다. 컴퓨터는 10과 20을 각 메모리셀에 저장하고 그에 대한 연산 결과인 30도 새로운 메모리셀에 저장한다. 이 때 30이라는 결과값을 재사용하기 위해 메모리 공간을 식별하기 위한 이름인 변수를 사용한다.
값에 직접 접근하는 것은 치명적인 오류가 발생할 가능성이 있기 때문에 자바스크립트는 개발자의 직접적인 메모리 제어를 허용하지 않는다. var result = 10 + 20
변수 이름을 식별자(identifier)라고도 한다. 식별자는 값이 저장되어 있는 메모리 주소와 매핑 관계를 맺고, 이 매핑 정보 또한 메모리에 저장된다. 식별자는 값이 아닌 메모리 주소를 기억한다. (변수 이름을 비롯한 모든 식별자는 실행 컨텍스트(execution context)에 등록된다. 자바스크립트 엔진은 실행 컨텍스트를 통해 식별자와 스코프를 관리한다.)
변수 선언이란, 변수를 생성하여 값을 저장하기 위한 메모리 공간을 확보하는 것을 말한다.
변수 선언에 의해 확보된 메모리 공간은 확보가 해제되기 전까지는 아무도 사용할 수 없게 보호된다.
변수 선언 키워드에는var, let, const
가 있다.
자바스크립트 엔진은 변수 선언 시 선언단계와 초기화 단계를 거쳐 수행된다.
때문에 var score;
와 같이 변수를 선언한다면, score에는 암묵적으로 undefined가 할당될 것이다.
만약 초기화 단계를 거치지 않으면 이전에 사용했던 값인 쓰레기 값(garbage value)가 남아있을 수 있기 때문에 꼭 초기화 단계를 거치게 된다.
변수 및 모든 식별자 사용 시 선언하지 않은 식별자에 접근하면 ReferenceError(참조 에러)가 발생한다.
console.log(score); // undefined
var score; // 변수 선언문
위 코드는 변수 선언문보다 변수를 참조하는 코드가 앞에 있지만, ReferenceError(참조 에러)
가 발생하지 않고 undefined
가 발생한다. 왜 그럴까?
자바스크립트 엔진은 런타임 이전에 먼저 소스코드의 평가 과정을 실행한다. 이 때 변수 선언을 포함한 모든 선언문(변수, 함수 선언문, class 등)을 찾아내 먼저 실행하게 된다. 이러한 평가 과정이 끝나면 비로소 런타임 환경에서 모든 선언문을 제외한 소스코드를 한 줄씩 순차적으로 실행한다.
이렇게 변수 선언문이 코드의 선두로 끌어 올려진 것처럼 동작하는 것을 변수 호이스팅 이라 한다.
var score = 80;
위 코드는 변수 선언과 값의 할당을 하나의 문으로 단축 표현한 것이다.
하지만 자바스크립트는 변수 선언과 값의 할당을 2개의 문으로 나누어 각각 실행하게 된다.
코드 평가 과정에서 변수를 선언한 뒤, 런타임 환경에서 값을 할당하는 것이다.
때문에 다음과 같은 식에서 첫번 째 콘솔이 실행될 때는 변수 선언만 된 상태이므로 undefined가 출력된다.
console.log(score); // undefined
var score = 80; // 1. 변수선언 2. 값의 할당
console.log(score) // 80
재할당이란 이미 값이 할당되어 있는 변수에 새로운 값을 할당하는 것이다.
만약 값을 재할당 할 수 없으면 변수가 아니라 상수(constant)라 한다.
💡 ES6에서 도입된
const
키워드를 사용하면 재할당이 금지된 상수를 표현할 수 있다. 하지만const
를 반드시 상수만을 위해 사용하지 않는다. (15장에서 더 자세히-!)
변수에 값을 재할당하면 이전 값이 저장되어 있던 메모리 공간을 지우고 재할당하는 것이 아니라, 새로운 메모리 공간을 확보하고 그 메모리 공간에 새로운 값을 할당하게 된다. 이 때 더 이상 필요하지 않는 이전 값들은 가비지 콜렉터에 의해 메모리에서 자동 삭제된다.
💡 가비지 콜렉터는 메모리 공간을 주기적으로 검사하여 더 이상 사용되지 않는 메모리를 해제한다. 자바스크립트는 매니지드 언어로써 내장된 가비지 콜렉터를 통해 메모리 누수를 방지한다.
- 매니지드 언어(managed language) : 메모리의 할당 및 해제 등의 관리 기능을 언어 차원에서 담당하고, 개발자의 직접적인 메모리 제어를 허용하지 않음 (언매니지드 언어 : C언어)
var first-name; // - 사용불가
var 1st; // 숫자로 시작 불가
var this; // 예약어 사용 불가
가독성을 좋게 하기 위해 규정한 명명규칙.
자바스크립트에서는 일반적으로 변수나 함수 이름에는 카멜 케이스를, 생성자 함수 및 클래스 이름에는 파스칼 케이스를 사용한다.
// 카멜 케이스
var firstName;
// 스네이크 케이스
var first_name;
// 파스칼 케이스
var FirstName;
// 헝가리언 케이스
var strFirstName; // 타입 + 식별자
var $elem = document.getElementById('myId) // DOM 노드
var observable$ = fromEvent(document, 'click') // RxJS 옵저버블
책의 예제를 인용한 것으로 var 키워드를 동일하게 사용하였습니다 :)