[JavaScript] 변수 (Variable)

jaylight·2021년 1월 17일
0

변수

10 + 20
  • 자바스크립트가 특정 소스코드를 평가(evaluation)하려면,
    1. 10, 20, + 라는 기호 (Literal & Operator)의 의미를 알고 있어야 함
    2. 10 + 20 이라는 식(Expression)의 의미도 해석(Parsing) 해야함
  • 컴퓨터는 CPU를 사용해 연산 & 메모리를 사용해 데이터를 기억

메모리 (Memory)

데이터를 저장할 수 있는 메모리 셀의 집합체

메모리 셀 하나의 크기 = 1바이트(8비트)

컴퓨터는 메모리 셀의 크기(1바이트) 단위로 데이터를 write & read

  • 메모리 주소

    메모리 공간의 위치를 나타냄

    0부터 시작해서 메모리 크기만큼 정수로 표현됨

    4GB 메모리의 메모리 주소

    • 0 ~ 4,294,967,295 (0x00000000 ~ 0xFFFFFFFF)
  • 컴퓨터는 모든 데이터의 종류(숫자, 텍스트, 이미지, 동영상 등)에 상관없이 2진수로 처리

CPU

메모리 상 임의의 위치(메모리 주소)에 저장된 값을 읽어 연산을 수행

연산된 결과 값은 다시 메모리 상 임의의 위치에 저장됨


변수 (Variable)

하나의 값을 저장하기 위해 확보한 메모리 공간 자체 혹은
메모리 공간을 식별하기 위해 붙인 이름 (값의 위치를 가리키는 상징적 위치)

프로그래밍 언어는 기억할 값을 메모리에 저장하고, 저장된 값을 읽어 재사용하기 위해 변수라는 매커니즘을 활용

변수는 프로그래밍 언어의 컴파일러 혹은 인터프리터에 의해 값이 저장된 메모리 공간 주소로 치환되어 실행

왜 특정 값 접근에 메모리 주소를 직접 활용하지 않을까?
1. 치명적 오류를 발생시킬 가능성이 높으므로, JavaScript는 개발자의 직접적 메모리 제어를 비허용

  • 실수로 운영체제가 사용 중인 값을 변경하면 시스템을 멈추게 하는 치명적 오류를 발생시킴
  1. 코드가 실행되기 전에는 값이 저장된 메모리 주소를 알 수 없음
    • 값이 저장되는 메모리 주소는 코드가 실행될 때 메모리 상황에 따라 임의로 결정
    • 동일한 코드를 실행해도 코드가 실행될때마다 값이 저장될 메모리 주소가 변경됨
  • 변수 이름(변수명): 메모리 공간에 저장된 값을 식별할 수 있는 고유한 이름

    변수 이름의 중요성
    저장된 값의 의미를 파악할 수 있는 변수 이름은 가독성을 높이는 효과가 있음
    개발자의 의도를 나타내는 명확한 네이밍은 코드를 이해하기 쉽게 만드고 협업과 품질향상에 도움

  • 변수 값: 변수에 저장된 값

  • 할당(Assignment) (대입, 저장): 변수에 값을 저장하는 것

  • 참조(Reference): 변수에 저장된 값을 읽어 들이는 것


식별자 (Identifier)

어떤 값을 구별해서 식별할 수 있는 고유한 이름

변수 이름을 식별자라고도 함

메모리 주소를 기억(저장)해서 메모리 공간에 저장된 어떤 값을 구별하여 식별해냄

식별자는 값이 아닌 메모리 주소를 기억한다.

즉, 식별자는 메모리 주소에 붙인 이름이라고 할 수 있다.

변수, 함수, 클래스 등의 이름은 모두 식별자이다.

즉, 메모리 상 존재하는 어떤 값을 식별할 수 있는 이름은 모두 식별자

식별자인 변수 이름 ⇒ 메모리 상 존재하는 변수 값을 식별
식별자인 함수 이름 ⇒ 메모리 상 존재하는 함수 (JavaScript에서 함수 = 값이다.)를 식별


변수 선언 (Variable Declaration)

값을 저장하기 위한 메모리 공간을 확보(allocate)하고 변수 이름과 확보된 메모리 공간의 주소를 연결(name binding)해서 값을 저장할 수 있게 준비하는 것

즉, 변수를 생성하는 것

변수 선언에 의해 확보된 메모리 공간은 확보가 해제되기 전까지 누구도 사용할 수 없도록 보호됨

변수 선언 키워드: var, let, const

키워드 (Keyword)

  • JavaScript 코드를 해석하고 실행하는 JavaScript 엔진이 수행할 동작을 규정한 일종의 명령어

  • var

    ES6 이전에 JavaScript에서 변수를 선언할 수 있는 유일한 키워드였음

    함수 레벨 스코프를 지원하며, 이로 인해 의도치 않게 전역변수가 선언되어 심각한 부작용이 발생하기도 함

    var score;

JavaScript의 변수 선언 단계

  • 선언 단계: 변수 이름을 등록해서 JavaScript 엔진에 변수의 존재를 알림

    실행 컨텍스트(Execution Context)

    • JavaScript 엔진이 소스코드를 평가하고 실행하기 위해 필요한 환경을 제공하고 실행 결과를 실제로 관리하는 영역
    • 변수 이름과 값은 실행 컨텐스트 내 키 / 값 형식의 객체로 등록되어 관리
  • 초기화 단계: 값을 저장하기 위한 메모리 공간을 확보하고 암묵적으로 undefined를 할당해 초기화

    초기화(Initialization): 변수가 선언된 이후 최초로 값을 할당하는 것을 의미

    변수 선언 이후 변수에 값을 할당하지 않는 경우, undefined라는 값이 암묵적으로 할당되어 초기화

    undefined

    • JavaScript에서 제공하는 원시 타입의 값(Primitive Value)

      초기화 단계를 거치지 않으면, 메모리 공간에 이전에 다른 애플리케이션에서 사용했던 값(Grabage Value)이 남아있을 수 있다.

      메모리 공간 확보 후 값을 할당하지 않고 곧바로 변수 값을 참조하면 Garbage Value가 나올 수 있으므로, 실제 값을 할당하지 않더라도 암묵적 초기화를 시행하여 이런 상황을 방지

      ReferenceError

    • 선언되지 않은 식별자에 접근했을 때, JavaScript 엔진이 등록된 식별자를 찾을 수 없어서 발생하는 에러

변수 선언 실행 시점

변수 선언은 런타임이 아니라 그 이전 단계인 소스코드 평가과정에서 실행

console.log(score);
var score;

위와 같이 score 변수 선언보다 먼저 console.log 를 실행하더라도 ReferenceError가 발생하지 않는다.

JavaScript는 인터프리터 언어이기 때문에 코드가 한 줄 씩 순차적으로 실행되지만,
코드를 한 줄씩 실행하는 시점(Runtime) 이전에 소스코드 평가과정이 있다.

이 과정에서 소스 코드 내의 모든 변수 선언이 먼저 실행됨

소스코드 평가과정

  • 변수 선언을 포함한 모든 선언문(변수 선언문, 함수 선언문 등)을 소스코드에서 찾아내 먼저 실행

  • 변수 호이스팅(Variable Hoisting)

    변수 선언문이 코드의 선두로 끌어 올려진 것처럼 동작하는 JavaScript 고유의 특징

    var, let, const, function, function*, class 등 키워드를 사용한 모든 식별자가 호이스팅 됨


값의 할당

할당 연산자 =을 활용해서 우변의 값을 좌변의 변수에 할당

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

var score = 80; // 변수 선언과 값의 할당을 하나의 문으로 표현

JavaScript는 변수 선언과 값 할당을 하나의 문으로 단축 표현해도 2개의 문으로 나누어 각각 실행함

변수 선언 시점 ≠ 값 할당 시점

변수 선언은 런타임 이전에, 값의 할당은 런타임에 실행됨

console.log(score); // undefined

var score = 80;

console.log(score); // 80

런타임 이전에 변수 선언 과정에서 score 변수를 선언해두고 이후 런타임 과정에서 해당 변수에 80 값을 저장

따라서 console.log를 통해 할당된 값이 출력되는 시점은 해당 변수에 값을 할당한 이후의 코드부터

값의 재할당

값이 할당된 변수에 현재 저장된 값을 버리고 새로운 값을 또다시 할당하는 것

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

변수는 저장된 값을 다른 값으로 변경할 수 있다는 의미를 내포

변수는 선언과 동시에 undefined로 초기화되기 때문에, 변수에 처음으로 값을 할당하는 것도 재할당

상수 (Constant)
값을 재할당할 수 없어서 변수에 저장된 값을 변경할 수 없는 값 (즉, 단 한 번만 할당할 수 있는 변수)
JavaScript에서는 ES6에서 도입된 const 키워드를 사용하여 상수를 표현

  • 변수 재할당의 과정

    기존 메모리 공간에 저장된 값을 지우고 새로운 값을 저장하는 것이 아니라,
    기존 식별자 - 메모리 주소의 연결을 끊고 새로운 주소의 메모리 공간을 확보하고 해당 메모리 공간에 새로운 값을 저장

    기존 메모리 공간에 남아있는 저장된 값들은 이후 가비지 콜렉터에 의해 메모리에서 자동 해제됨

가비지 콜렉터 (Garbage Collector)
-
애플리케이션이 할당(allocate)한 메모리 공간을 주기적으로 검사하여 사용하지 않는 메모리(어떤 식별자도 참조하지 않는 메모리 공간)를 해제(release)하는 기능
- JavaScript는 가비지 콜렉터를 내장한 매니지드 언어로, 이를 통해 메모리 누수를 방지

Unmanaged Language vs Managed Languge
- 프로그래밍 언어는 메모리 관리 방식에 따라 언매니지드 언어매니지드 언어로 분류
- 언매니지드 언어 (Unmanaged Language)
- 개발자가 명시적으로 메모리를 할당하고 해제
- C 언어 같은 경우 malloc(), free() 와 같은 저수준 메모리 제어 기능을 제공
- 개발자가 직접 메모리 제어를 하며 개발자 역량에 따라 최적의 성능을 확보할 수 있지만,
그 반대의 경우 치명적 오류를 생산할 가능성이 있음
- 매니지드 언어 (Managed Language)
- 언어 차원에서 메모리 관리 기능(할당 및 해제)을 담당, 개발자의 직접적 메모리 제어를 비허용
- 더 이상 사용하지 않는 메모리 해제는 가비지 콜렉터가 수행
- 개발자 역량에 의존하지 않아 어느 정도 일정한 생산성 확보가 가능하지만,
성능 면에서 어느 정도의 손실을 감수할 수 밖에 없음


식별자 네이밍 규칙

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

ES5부터 식별자에 유니코드 문자가 허용되어, 한글이나 일본어 식별자도 사용할 수 있지만, 권장하지 않음

식별자는 대소문자가 구별됨

변수의 존재 목적을 쉽게 이해할 수 있도록 의미를 명확히 표현하여 가독성을 높일 것

네이밍 컨벤션

// 카멜 케이스
var firstName;

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

// 파스칼 케이스
var FirstName;

// 헝가리언 케이스
var strFirstName;
var $elm = document.getElementById('myID'); // DOM 노드
var observable$ = fromEvent(document, 'click') // RxJS 옵저버블

JavaScript는 일반적으로

  • 변수 & 함수 이름은 카멜 케이스
  • 생성자 & 클래스 이름은 파스칼 케이스를 사용

0개의 댓글