[모던 자바스크립트 Deep Dive] 04장. 변수

윤상준·2022년 10월 10일
0
post-thumbnail

4.1 변수란 무엇인가? 왜 필요한가?

변수
데이터를 관리하기 위한 핵심 개념.

코드 평가 (Code Evaluation)

자바스크립트 엔진이 다음의 코드를 평가하는 과정은 다음과 같다.

10 + 20
  • 10, 20 (피연산자 : Operand) 의 의미를 파악하여 기억.
    • 라는 기호 (연산자 : Literal) 의 의미를 파악.
  • 10 + 20 이라는 식 (표현식 : Operator) 의 의미를 해석 (파싱 : Parsing).
  • 식을 연산.

메모리 (Memory)

메모리
데이터를 저장할 수 있는 메모리 셀 (Memory Cell)의 집합체.

메모리 셀 하나의 크기: 1바이트 (8비트).
컴퓨터는 메모리 셀의 크기 (1바이트) 단위로 데이터를 저장 (Write) 하거나 읽어 (Read) 들인다.

메모리 주소 (Memory Address)

메모리 주소
각 셀은 고유의 메모리 주소를 갖는다.

  • 메모리 공간의 위치.
  • 0 부터 시작해서 메모리 크기 만큼 정수로 표현.
  • 메모리에 저장되는 데이터는 종류와 상관 없이 2진수로 저장.

예시
4GB 메모리는 0부터 4,294,967,295 (0x00000000 ~ 0xFFFFFFFF) 까지의 메모리 주소를 갖는다.

메모리 저장

데이터는 메모리 상의 임의의 위치 (메모리 주소)에 기억 (저장).

10 + 20
  • 10, 20은 메모리 상의 임의의 위치에 저장.
  • CPU는 이를 읽고 연산.
  • 연산 결과 30은 메모리 상의 임의의 위치에 저장.

메모리 상의 데이터를 사용하는 방법

메모리 상의 값을 사용하려면 메모리 공간에 직접 접근해야 한다.

자바스크립트는 개발자의 직접적인 메모리 제어를 허용하지 않는다.
메모리 상에 직접 접근면 치명적 오류 발생 가능.

코드가 실행될 때마다 메모리 주소는 변경된다.
코드가 실행되기 전에는 메모리 주소를 알 수 없어서 접근이 불가능.

따라서, 메모리 상의 값을 불러올 수 있는 매개체가 필요하다.

변수 (Variable)

변수

  • 하나의 값을 저장하기 위해 확보한 메모리 공간 자체 또는 식별하기 위해 붙인 이름.
  • 값을 저장하고 참조하는 매커니즘.
  • 값의 위치를 가리키는 상징적인 이름.

변수는 컴파일러 또는 인터프리터에 의해 해당 메모리 주소로 치환되어 실행.
변수를 통해 값에 안전하게 접근 가능.

// 변수는 하나의 값을 저장하기 위한 수단이다.
var userId = 1;
var userName = 'Lee';

// 객체나 배열 같은 자료구조를 사용하면 여러 개의 값을 하나로 그룹화해서 하나의 값처럼 사용할 수 있다.
var user = { id: 1, name: 'Lee' };

var users = [
  { id: 1, name: 'Lee' },
  { id: 2, name: 'Kim' }
];

변수 이름 (변수명)

메모리 공간에 저장된 값을 식별할 수 있는 고유한 이름.

변수 이름과 매핑된 메모리 주소를 통해 메모리 공간에서 값을 불러온다.
저장된 값의 의미를 내포하여 가독성을 높일 수 있다.

변수 값

변수에 저장된 값.

할당 (Assignment, 대입, 저장)

변수에 값을 저장하는 것.

참조 (Reference)

변수에 저장된 값을 읽어 들이는 것.

4.2 식별자 (Identifier)

식별자

  • 어떤 값을 구별 및 식별할 수 있는 고유한 이름.
  • 값이 저장되어있는 메모리 주소와 매핑 관계를 맺는다.
  • 이 매핑 정보 역시 메모리에 저장.
  • 값이 아니라 메모리 주소를 기억한다.

메모리 상에 존재하는 값을 식별할 수 있는 이름은 모두 식별자. (변수, 함수, 클래스 등)
변수 이름 : 메모리 상에 존재하는 변수 값을 식별.
함수 이름 : 메모리 상에 존재하는 함수를 식별.

4.3 변수 선언 (Variable Declaration)

변수 선언
변수를 생성하는 것.

값을 저장하기 위해 메모리 공간을 확보 (Allocate).
변수 이름과 확보된 메모리 공간의 주소를 연결 (Name Binding).
확보가 해제 (Release)되기 전까지는 안전하게 사용 가능.

변수 선언 키워드

변수를 선언할 때는 var, let, const 키워드를 사용.

키워드 (Keyword)
자바스크립트 엔진이 코드를 해석, 실행하도록 동작을 규정한 명령어.

ES5까지는 var만 존재.
var의 단점 (스코프, 호이스팅)을 보완하여 ES6부터 let, const가 등장.

var score; // 변수 선언(변수 선언문)

변수 선언문을 만나면 변수 이름을 등록하고 값을 저장할 메모리 공간을 확보한다.

확보된 메모리 공간은 자동으로 undefined가 할당되어 초기화. (자바스크립트의 특징)

변수 선언 단계

선언 단계

변수 이름을 등록해서 자바스크립트 엔진에 변수 존재를 알린다.

변수 이름은 실행 컨텍스트 (Execution Context) 에 저장. (23장에서 계속)

초기화 단계

값을 저장하기 위한 메모리 공간 확보.
메모리 공간 확보 후 최초의 값을 할당.

초기화를 하지 않으면 메모리 공간에 이전 어플리케이션에서 사용했던 값 (쓰레기 값, Garbage Value)이 남아있을 수 있다.

ReferenceError

자바스크립트 엔진이 등록된 식별자를 찾을 수 없을 때 발생하는 에러.

var를 사용한 변수 선언

선언 단계초기화 단계가 동시에 진행.
var는 초기화 단계에서 자동으로 undefined 할당.

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

console.log(score); // undefined

var score; // 변수 선언문

score 선언 이전에 console.log()가 있으므로 ReferenceError가 뜰 것 같지만 undefined가 뜬다.

변수 선언이 런타임 이전 단계에서 먼저 실행되기 때문.

런타임 (Runtime)
소스코드가 한 줄씩 순차적으로 실행되는 시점.

소스코드 평가

자바스크립트 엔진은 소스코드를 실행하기 전에 소스코드를 평가.

평가 과정에서 모든 선언문 (변수, 함수 등)만 찾아서 먼저 실행. (어디에 있던지 상관 없이) 평가 과정이 끝나면 모든 선언문을 제외한 나머지 코드를 한 줄씩 실행.

var에서 소스코드 평가

var는 변수 선언과 동시에 undefined로 초기화되기 때문에, 선언문 이전에 console.log를 만나도 undefined가 출력.

호이스팅 (Hoisting)

호이스팅
선언문의 코드의 최상단으로 끌어 올려진 것처럼 동작하는 현상.
모든 선언문은 런타임 이전 단계에서 먼저 실행되기 때문.

var의 경우처럼 선언문 이전에 접근이 가능한 경우를 호이스팅이라고 한다.
var, let, const, function, function*, class 키워드 등 모든 식별자는 호이스팅된다.

4.5 값의 할당

할당 연산자 (=)를 통해 변수에 값을 할당 (Assignment)할 수 있다.
변수 할당은 2개 또는 1개의 문 (Statement)으로 할 수 있다.

var score;  // 변수 선언
score = 80; // 값의 할당

var score = 80; // 변수 선언과 값의 할당

어떻게 작성해도 자바스크립트 엔진은 변수 선언값의 할당을 항상 2개의 문으로 나누어 각각 실행.

변수 선언은 런타임 이전에 실행되고 값의 할당은 런타임에 실행.

console.log(score); // undefined

var score;  // ① 변수 선언
score = 80; // ② 값의 할당

console.log(score); // 80

4.6 값의 재할당

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

var score = 80; // 변수 선언과 값의 할당
score = 90;     // 값의 재할당

var, let은 재할당이 가능.

상수 (Constant)
값을 재할당할 수 없어서 변수에 저장된 값을 변경할 수 없는 변수.
const 키워드를 사용해 선언 가능.

재할당은 기존의 메모리 공간을 지우고 새로운 값을 할당하는 것이 아닏.
기존의 메모리 공간은 그대로 두고, 새로운 메모리 공간에 값을 할당.

score 변수에 90이 재할당되었으므로, undefined와 80은 더 이상 필요하지 않은 쓰레기 값 (Garbage Value)이 됨.
쓰레기 값은 가비지 콜렉터 (Garbage Collector)에 의해 자동으로 메모리에서 해제 된다.

카비지 콜렉터
어플리케이션이 할당한 메모리 공간을 주기적으로 검사하여, 더 이상 사용되지 않는 메모리를 해제하는 기능.

사용되지 않는 메모리
어떤 식별자도 참조하지 않는 메모리 공간.

자바스크립트는 가비지 콜렉터를 내장하고 있는 매니지드 언어 (Managed Language).
자동으로 가비지 콜렉터를 동작하여 메모리 누수 (Memory Leak)를 방지.

언매니지드 언어 (Unmanaged Language)
개발자가 malloc(), free() 등의 저수준의 메모리 제어 기능을 통해, 직접 메모리 할당 및 해제가 가능.

매니지드 언어 (Managed Language)
메모리 관리는 언어가 담당하고 개발자의 직접적인 제어를 비허용.

4.7 식별자 네이밍 규칙

식별자는 다음과 같은 네이밍 규칙을 준수해야 한다.

  • 특수문자를 제외한 문자, 숫자, 언더스코어 (_), 달러 ($)를 포함할 수 있다.
  • 숫자로 시작할 수 없다.
  • 예약어를 사용할 수 없다.

예약어
프로그래밍 언어에서 사용되고 있거나 사용될 예정인 단어.

  • 쉼표(,)로 구분하여 하나의 문에서 여러 개를 한번에 선언할 수 있지만 권장하지 않는다.
  • 알파벳 외의 유니코드를 사용하는 것은 권장하지 않는다.
var 이름, なまえ;
// 불가능
var first-name; // SyntaxError: Unexpected token –
var 1st;        // SyntaxError: Invalid or unexpected token
var this;       // SyntaxError: Unexpected token this
// 대소문자를 구별.
// 서로 다른 변수.
var firstname;
var firstName;
var FIRSTNAME;

네이밍 컨벤션 (Naming Convention)

네이밍 컨벤션
가독성 좋게 단어를 한눈에 구분하기 위한 명명 규칙.

  • 일반적으로 변수, 함수는 카멜 케이스를 사용.
  • 일반적으로 생성자 함수, 클래스는 파스칼 케이스를 사용.

카멜 케이스 (CamelCase)

var firstName;

스네이크 케이스 (snake_case)

var first_name;

파스칼 케이스 (PascalCase)

var FirstName;

헝가리언 케이스 (typeHungarianCase)

var strFirstName; // type + identifier
var $elem = document.getElementById('myId'); // DOM 노드
var observable$ = fromEvent(document, 'click'); // RxJS 옵저버블
profile
하고싶은건 많은데 시간이 없다!

0개의 댓글