변수 : 프로그래밍 언어에서 데이터를 관리하기 위한 핵심 개념
10 + 20
자바스크립트 엔진이 10 + 20
이라는 자바스크립트 코드를 계산(평가, evaluation)하려면,
10
, 20
, +
의 의미를 알고 있어야 하며, 10 + 20
이라는 식(표현식, expression)의 의미를 해석(파싱)할 수 있어야 한다.자바스크립트 엔진이 10 + 20
이라는 식의 의미를 해석(파싱)하면,
+
연산을 수행하기 위해 먼저 좌변과 우변의 숫자(피연산자)를 저장한다.
메모리 : 데이터를 저장할 수 있는 메모리 셀의 집합체
메모리 셀 하나의 크기는 1바이트(8비트)이며, 컴퓨터는 메모리 셀 크기 단위로 데이터를 저장하거나 읽어들인다.
각 셀은 고유의 메모리 주소를 갖는다. 메모리 주소는 메모리 공간의 위치를 나타내며,
0부터 시작해 메모리 크기만큼 정수로 표현된다. (ex. 4GB 메모리는 0x00000000 ~ 0xFFFFFFFF)
메모리에 저장되는 데이터는 모두 2진수이다. (그림에서는 임의로 10진수로 나타내었습니다)
피연산자는 메모리 상 임의의 위치(메모리 주소)에 저장되고 CPU는 이 값을 읽어들여 연산을 수행한다.
그렇다면 이렇게 연산되고 저장된 결과 값(30)을 어떻게 재사용할까?
자바스크립트는 개발자의 직접적인 메모리 제어를 허용하지 않는다.
그래서,
프로그래밍 언어는 기억하고 싶은 값을 메모리에 저장하고 참조하여 재사용하기 위해
'변수'
라는 메커니즘을 제공한다.
변수
하나의 값
을 저장하기 위해 확보된 메모리 공간 자체
식별
하기 위해 메모리 주소에 붙인 이름변수를 사용하면 언어의 컴파일러
또는 인터프리터
에 의해 값이 저장된 메모리 공간의 주소로 치환되어 실행되므로 안전하게 값에 접근할 수 있다.
var result = 10 + 20;
// undefined
// 할당 : 변수에 값을 저장하는 것(대입, 저장)
result;
// 30
// 참조 : 변수에 저장된 값을 읽어 들이는 것
변수 이름을 사용해 참조를 요청하면 자바스크립트 엔진은 변수 이름과 매핑된 메모리 주소를 통해
메모리 공간에 접근해 저장된 값을 반환
한다.
변수 이름을 식별자라고도 한다.
식별자 : 어떤 값을 구별해서 식별할 수 있는 고유한 이름
메모리 공간에 저장된 어떤 값을 구별해서 식별해내기 위해
식별자
는 어떤 값이 저장되어 있는 메모리 주소를 저장
해야한다.
식별자
는 값이 저장되어 있는 메모리 주소
와 매핑
관계. 매핑 정보도 메모리에 저장된다.이름
으로 메모리 상에 존재하는 값을 식별
한다. 즉, 식별자는 메모리 주소의 이름메모리 상에 존재하는 어떤 값을 식별할 수 있는 이름은 모두 식별자
식별자는 네이밍 규칙
을 준수해야 하며, 선언
으로 자바스크립트 엔진에 식별자의 존재를 알린다.
ex. var result = 30;
변수를 사용하려면 반드시 선언이 필요하다.
var
:블록 레벨 스코프
를 지원하지 않고함수 레벨 스코프
를 지원한다.
의도치 않게 전역 변수가 선언되어 부작용이 발생할 수 있다.
ES6(ES5의 상위 집합)에서 보완해서 등장한 것이let
,const
=>var
let
const
는키워드
다. 자바스크립트 엔진은 키워드를 만나면 약속된 동작을 수행한다.
var score;
// 선언 : 변수 이름 등록, 자바스크립트 엔진에 변수 존재 알리기
// 초기화 : 값 저장을 위한 메모리 공간 확보. 초기화가 없으면 쓰레기 값이 나올 수도 있지만 `var` 키워드를 사용한 선언에서는 자바스크립트 엔진이 암묵적으로 `undefined`(원시 타입의 값)값을 할당해 초기화한다.
변수 이름을 비롯한 식별자는 실행 컨텍스트에 등록된다.
실행 컨텍스트 : 자바스크립트 엔진이 소스코드를 평가하고 실행하기 위해 필요한 환경을 제공하고 코드 실행 결과를 실제로 관리하는 영역. 자바스크립트 엔진은 실행 컨텍스트를 통해 식별자와 스코프를 관리한다.
변수 이름과 변수 값은키
/값
형식인 객체로 등록되어 관리된다.
선언하지 않은 식별자에 접근하면 ReferenceError
참조 에러가 발생한다.
자바스크립트 코드는 인터프리터에 의해 한 줄씩 순차적으로 실행된다.
하지만 변수 선언은 런타임이 아니라 그 이전 단계에서 먼저 실행된다.
console.log(score) ; // undefined
var score; // 변수 선언문
소스코드 평가 과정
: 소스코드 실행 준비 (모든 선언문 실행)런타임 단계
: 모든 선언문을 제외하고 소스코드를 한 줄씩 순차적으로 실행이것을 변수 호이스팅
이라고 한다.
변수 호이스팅 : 변수 선언문이 코드의 선두로 끌어 올려진 것처럼 동작하는 자바스크립트 고유의 특징
모든 식별자
var
,let
,const
,function
,function*
,class
키워드로 선언하는 모든 식별자는 모두호이스팅
된다.
변수에 값을 할당할 때는 할당 연산자 = 를 사용해 우변의 값
을 좌변의 변수
에 할당
var score; // 변수 선언
score = 80; // 값의 할당
var score = 80; // 변수 선언과 값의 할당
변수 선언과 할당이 한 줄로 이루어질 때도, 실행 시점이 다르다.
값의 할당은 런타임에 실행된다.
다음 코드를 실행시켜보자.
console.log(score); // 3. undefined
var score; // 1. 변수 선언
score = 80; // 2. 값의 할당
console.log(score); // 4. 80
다음 실행 결과도 동일하게 동작한다.
console.log(score); // undefined
var score = 80;
console.log(score); // 80
console.log(score) // undefined
score = 80;
var score;
console.log(score) // 80
새로운 공간을 확보해서 저장하는 것. 저장된 값을 다른 값으로 변경한다.
var
키워드로 선언한 변수는 선언과 동시에 undefined
로 초기화되므로 처음으로 값을 할당하는 것도 재할당이다.
var score = 80;
score = 90;
식별자와 연결되지 않은 (연결이 해제된) 값은
가비지 콜렉터
에 의해 메모리에서 자동 해제된다. 이 시점은 예측 불가하다.
자바스크립트는 가비지 콜렉터를 내장하고 있는매니지드 언어
(언어 차원에서 메모리 관리)로서 가비지 콜렉터를 통해 메모리 누수를 방지한다.
단 한 번만 할당할 수 있는 변수
값을 재할당할 수 없어서 변수에 저장된 값을 변경할 수 없다면 변수가 아니라 상수이다.
ES6에서 도입된
const
키워드를 사용해 선언한 변수는 재할당이 금지된다.
// 카멜 케이스 (변수, 함수)
var firstName;
// 파스칼 케이스 (생성자 함수, 클래스 이름)
var FirstName;
// 스네이크 케이스
var first_name;
// 헝가리언 케이스
var strFirstName
ECMAScript 사양에 정의된 객체, 함수들은 카멜/파스칼 케이스를 사용하고 있다.