[4장, 5장] 변수 ~ 표현식과 문

Sheryl Yun·2022년 6월 3일
0
post-thumbnail

4장

변수가 필요한 이유

자바스크립트가 어떤 연산을 수행하면 연산에 사용한 값들과 연산자, 연산한 결과값 등을 메모리에 저장한다.
이렇게 코드를 '실행'한 후 메모리 상의 임의의 공간에 값을 저장하게 되는데 이 값을 다시 사용(재사용)하려면 다음과 같은 2가지 문제가 생긴다.

  1. 재사용할 값을 찾기 위해 메모리 공간에 '직접' 접근해야 하는데, 이 방법은 만약 운영체제와 관련된 메모리를 건드리게 될 경우 매우 위험할 수 있다.
  2. 코드가 실행될 때마다 연관된 값들을 매번 메모리의 임의의 다른 공간에 계속 저장하는데, 이는 코드가 실행되기 전까지는 값이 어디에 저장되는지 알 수가 없다는 뜻이어서 어차피 메모리에 직접 접근해서 값을 수정하는 것 자체가 쉽지 않다.

따라서 이러한 문제를 해결하기 위해 변수가 등장했다.
변수는 하나의 값을 저장하기 위해 확보한 메모리 공간 자체 또는 그 메모리 공간을 '식별'하기 위해 붙인 이름을 말한다.

즉 변수명이란 값의 위치를 나타내는 상징적인 이름으로서, 개발자가 메모리에 직접 접근하지 않고 변수를 '참조'하여 값을 조회하거나 수정할 수 있도록 한다.
메모리 공간에 이름을 붙여 놓았으므로 코드 실행 때마다 매번 새로운 메모리 공간을 할당하지 않아도 되고, 값을 수정할 때도 변수 이름을 사용하면 그 변수명과 매핑된 값을 참조할 수 있게 되어 메모리에 대한 직접적인 접근을 막을 수 있다. 또한 이로 인해 이미 한번 할당했던 메모리를 '재사용'하는 것도 용이해진다는 장점이 있다.

변수 하나에는 하나의 값만 저장하는 게 원칙이나, 여러 개의 값을 저장하고 싶은 경우에는 배열이나 객체와 같은 자료구조를 사용하면 된다.

'코드는 개발자를 위한 문서이다'라는 말에서의 코드에는 '변수명'도 포함된다. 가독성 있는 변수명은 주석이 따로 필요없는 변수명이다.

식별자

어떤 값을 구별해서 식별할 수 있는 고유한 이름
식별자 중에는 변수뿐만 아니라 함수, 클래스 등도 포함된다.
식별자는 값 자체가 아닌 메모리 주소를 기억하고 있다.
따라서 변수를 통해 값에 접근하면 변수가 메모리 주소를 기억하고 있다가 해당 주소의 메모리 셀에 담긴 값을 참조한다.

식별자는 '선언(declaration)'을 통해 자바스크립트 엔진에게 자신의 존재를 알린다.

변수 선언

변수 선언이란 변수를 생성하는 것을 말한다.
변수를 생성한다는 것은, 값을 저장할 메모리 공간을 확보(allocate)하고
변수명을 등록하고, 변수명과 해당 메모리의 주소를 연결(binding)하여
값을 저장할 수 있도록 준비하는 과정이다.

변수는 반드시 '선언'되어야 사용할 수 있다.
선언되지 않은 식별자에 접근하면 ReferenceError(참조 에러)가 발생한다.
변수를 선언할 때의 키워드는 var, let, const가 있다.

var로 변수를 선언하면 특정 값이 할당되기 전에 자바스크립트가 미리 임의로 undefined라는 값을 넣어 놓는다. 이를 '암묵적으로 undefined를 할당해 초기화한다' 고 말한다.

초기화란?
변수가 선언된 이후 최초로 값을 할당하는 것

JS의 변수 선언 단계

  1. 선언 단계: 변수명 등록 => 자바스크립트 엔진에 변수의 존재를 알림

    변수명은 실행 컨텍스트(execution context)에 등록된다.
    변수명과 변수 값은 실행 컨텍스트 내에 각각 key와 value 형태로 등록되어 객체로 관리된다.

  2. 초기화 단계: 메모리 공간 확보 + 암묵적으로 undefined 할당

초기화를 해 두지 않으면 확보된 메모리 공간에 이전에 다른 애플리케이션이 사용했던 '쓰레기 값(garbage value)'이 남아있을 수 있다.
따라서, 메모리 공간을 확보한 후 값을 할당하지 않은 상태에서 곧바로 변수 값을 참조하면 쓰레기 값이 나올 수 있는데 var로 선언하면 이러한 위험에서 안전하다.

🌠 변수 호이스팅

console.log(score);

var score;

위의 코드에서 변수를 선언하는 문보다 변수를 참조하여 출력하는 문이 앞에 있다.
아직 변수가 선언되지 않은 상태에서 참조를 했으므로 ReferenceError(참조 에러)가 뜰 것 같지만 의외로 에러 없이 undefined라는 정상적인 값을 출력한다.

이유는 자바스크립트 코드는 실행이 되면 전체 소스코드의 평가 과정(스캔)을 거치면서 선언문들만 찾아 먼저 실행한 뒤 나머지 코드들(예: 할당문)을 순차적으로 실행하기 때문이다.

즉, 선언문들은 코드가 실행되는 런타임 시점 이전에 이미 스캔되어 실행된 상태이다. var 키워드로 선언된 변수는 이 시점에 undefined로 미리 초기화되는 특징이 있다.

var 변수 외에도 특정 키워드(var, let, const, function, function*, class)로 선언된 모든 선언문은 위치에 상관없이 런타임 이전 단계에서 실행된다. 따라서 선언문 코드는 소스코드의 어디에 위치하든지 항상 참조가 가능하다.

이처럼 선언문이 코드의 '선두'로 끌어올려진 것처럼 동작하는 자바스크립트 고유의 특징을 호이스팅이라고 한다.

할당

변수 선언은 위의 설명처럼 런타임 이전 단계에서 실행되지만, 변수에 특정 값을 할당하는 것은 실제 런타임 단계에서 실행된다.

따라서 다음과 같은 출력결과가 가능하다.

console.log(score); // undefined

var score = 80;

console.log(score); // 80

값이 할당되기 전 참조를 먼저 하면 런타임 이전 스캔 단계에서 부여된 undefined가 출력되지만 할당문이 실행된 후에는 할당된 값인 80이 출력된다.

이때 이전 undefined가 들어있던 메모리 공간에서는 들어있던 undefined를 80으로 '수정'하는 것이 아니라, undefined가 있는 메모리 공간은 그대로 두고 새로운 메모리 공간을 만들어 거기에 80을 할당한다.
그러면 변수명이 새로이 만들어진 80이 들어있는 메모리의 주소를 가리키게 되고, 이전의 undefined가 들어있던 메모리는 참조를 안 하게 된다.
참조가 안 되는 메모리 공간은 자바스크립트가 더 이상 쓰이지 않는다고 판단하고 가비지 콜렉터(GC)를 실행시켜 해당 메모리 공간을 해제한다.

가비지 콜렉터(Garbage Collector)란?
할당된 메모리 공간을 주기적으로 검사하여 더 이상 사용되지 않는 메모를 해제(release)하는 기능
자바스크립트는 GC를 내장하고 있는 매니지드(managed) 언어로서, GC를 통해 메모리 누수(= 쓸데없는 메모리 공간이 남아 있어 메모리를 낭비하는 것)를 방지한다.

재할당

이미 값이 할당되어 있는 변수에 새로운 값을 또다시 할당하는 것
(위에서 본 것처럼 기존 메모리 값을 대체하는 게 아니라 새로운 메모리를 만들어 값을 넣고 변수명이 그곳을 가리키게 함)

이처럼 재할당을 통해 변수에 저장된(= 변수가 가리키고 있는) 값을 다른 값으로 '변경'할 수 있다. 그래서 이를 '변수'라고 한다.
만약에 값을 재할당할 수 없으면 '상수'라고 한다. 상수(constant)는 한 번 정해지면 더 이상 변하지 않는 값이다. 즉, 상수는 '단 한 번만 할당할 수 있는 변수'다.

식별자 네이밍 규칙

  1. 특수문자를 제외한 문자, 숫자, underscore(_), 달러($) 포함 가능
  2. 위의 경우들로 시작 가능 but 숫자로 시작하는 건 허용 x
  3. 예약어(reserved word)는 사용 불가
    (예약어 - var, if, function, await 등 자바스크립트 내에서 자체 기능을 가지고 있는 키워드)

🌠 네이밍 컨벤션 4가지

// 1. 카멜 케이스
var firstName;

// 2. 스네이크 케이스
var first_name;

// 3. 파스칼 게이스
var FirstName;

// 4. 헝가리안 케이스
var strFirstName;
var $elem = document.getElementById('myId'); // DOM 노드

자바스크립트에서는 일반적으로 카멜 케이스와 파스칼 케이스를 사용

  • 카멜 케이스 - 변수명 또는 함수명
  • 파스칼 케이스 - 생성자 함수 또는 클래스명

5장 표현식과 문

개념을 이해한다는 것은 '용어를 정확히 이해하고 설명할 수 있다'는 뜻이다.

값(value)

표현식(expression)이 평가되어 생성된 결과

평가(evaluate)란?
표현식을 해석해서 값을 생성하거나 참조하는 것

변수는 하나의 '값'을 저장하기 위해 확보한 메모리 공간 또는 그 메모리 공간을 식별하는 이름이다.

리터럴(literal)

값을 생성하는 방법 중 하나
사람이 이해할 수 있는 문자(아라비아 숫자, 알파벳, 한글 등) 또는 약속된 기호('', "", [], {}, // 등)를 사용해 값을 생성하는 표기법

예시

코드 상의 '3'은 단순한 아라비아 숫자가 아니라 숫자 리터럴이다.
사람이 이해할 수 있는 아라비아 숫자를 컴퓨터가 이해할 수 있는 문자(리터럴)로 사용한 것일 뿐이다.
따라서 숫자 3을 코드에 기술하면 자바스크립트 엔진은 이를 평가하여 숫자값(number) 3을 생성한다.

표현식(expression)

'값'으로 평가될 수 있는 문(statement)
값으로 평가될 수 있는지 여부는 변수에 할당할 수 있는지 여부로 판단 가능하다.
예를 들어 10 + 20 과 같은 연산은 변수에 할당할 수 있으므로 표현식이지만,
var x; 와 같은 변수 선언문은 변수에 할당하면 var exp = var x; 와 같은 비문이 되기 때문에 표현식이 아니다.

문(statement)

프로그램을 구성하는 기본 단위이자 최소 실행 단위
문의 집합으로 이뤄진 것이 바로 프로그램이며,
문을 작성하고 순서에 맞게 나열하는 것이 바로 프로그래밍이다.

문은 여러 토큰으로 구성된다.

토큰(token)

문법적으로 더 이상 나눌 수 없는 코드의 기본 요소
var sum = 1 + 2 라는 문장이 있다면 var, sum, =, 1, +, 2 각각이 토큰이다. (국어 시간에 배운 형태소와 유사)

세미콜론(semicolon)

문의 종료를 나타낸다.
프로그램은 여러 문의 집합으로 이루어지는데,
자바스크립트 엔진은 세미콜론을 통해 각각의 문이 어디에서 종료되는지를 파악한다.
따라서 문이 끝날 때는 반드시 세미콜론이 붙어야 한다.

그러나 if문, for문, 함수 등의 끝에는 세미콜론을 붙이지 않아도 된다.
이러한 코드 블록은 그 자체로 문의 종료를 의미하는 자체 종결성(self-closing)을 갖기 때문이다.

세미콜론은 코드 작성 시 생략을 해도 되는데, 이는 자바스크립트 엔진이 소스코드를 해석하면서 문의 끝이라고 추측되는 부분에 자동으로 세미콜론을 붙여주기 때문이다. (세미콜론 자동 삽입 기능 - Automatic Semicolon Insertion, ASI)

profile
데이터 분석가 준비 중입니다 (티스토리에 기록: https://cherylog.tistory.com/)

0개의 댓글