[JavaScript] 변수

jiseung·2022년 4월 4일
4
post-thumbnail

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

자바스크립트 코드의 실행

변수 : 프로그래밍 언어에서 데이터를 관리하기 위한 핵심 개념

10 + 20
자바스크립트 엔진이 10 + 20이라는 자바스크립트 코드를 계산(평가, evaluation)하려면,

  1. 10, 20, + 의 의미를 알고 있어야 하며,
  2. 10 + 20이라는 식(표현식, expression)의 의미를 해석(파싱)할 수 있어야 한다.

자바스크립트 엔진이 10 + 20이라는 식의 의미를 해석(파싱)하면,
+ 연산을 수행하기 위해 먼저 좌변과 우변의 숫자(피연산자)를 저장한다.

메모리

메모리 : 데이터를 저장할 수 있는 메모리 셀의 집합체
메모리 셀 하나의 크기는 1바이트(8비트)이며, 컴퓨터는 메모리 셀 크기 단위로 데이터를 저장하거나 읽어들인다.

각 셀은 고유의 메모리 주소를 갖는다. 메모리 주소는 메모리 공간의 위치를 나타내며,
0부터 시작해 메모리 크기만큼 정수로 표현된다. (ex. 4GB 메모리는 0x00000000 ~ 0xFFFFFFFF)
메모리에 저장되는 데이터는 모두 2진수이다. (그림에서는 임의로 10진수로 나타내었습니다)

피연산자는 메모리 상 임의의 위치(메모리 주소)에 저장되고 CPU는 이 값을 읽어들여 연산을 수행한다.

그렇다면 이렇게 연산되고 저장된 결과 값(30)을 어떻게 재사용할까?

저장하고 읽어들이는 방법

자바스크립트는 개발자의 직접적인 메모리 제어를 허용하지 않는다.

  • 실수로 운영체제가 사용하고 있는 값을 변경하면 시스템이 멈출 수 있다.
  • 값이 저장될 메모리 주소는 코드가 실행될 때마다 메모리 상황에 따라 임의로 결정되므로 코드가 실행되기 이전에 메모리 주소를 알 수 없다.

그래서,

프로그래밍 언어는 기억하고 싶은 값을 메모리에 저장하고 참조하여 재사용하기 위해 '변수'라는 메커니즘을 제공한다.

변수

  1. 하나의 값을 저장하기 위해 확보된 메모리 공간 자체
    => 여러 개의 값은 배열, 객체 같은 자료구조로 그룹화해서 저장할 수 있다.
  2. 그 메모리 공간을 식별하기 위해 메모리 주소에 붙인 이름
    => 값의 위치를 가리키는 상징적인 이름

변수를 사용하면 언어의 컴파일러 또는 인터프리터에 의해 값이 저장된 메모리 공간의 주소로 치환되어 실행되므로 안전하게 값에 접근할 수 있다.

var result = 10 + 20;
// undefined
// 할당 : 변수에 값을 저장하는 것(대입, 저장)
result;
// 30
// 참조 : 변수에 저장된 값을 읽어 들이는 것

변수 이름을 사용해 참조를 요청하면 자바스크립트 엔진은 변수 이름과 매핑된 메모리 주소를 통해 메모리 공간에 접근해 저장된 값을 반환한다.

2. 식별자

변수 이름을 식별자라고도 한다.
식별자 : 어떤 값을 구별해서 식별할 수 있는 고유한 이름

메모리 공간에 저장된 어떤 값을 구별해서 식별해내기 위해
식별자는 어떤 값이 저장되어 있는 메모리 주소를 저장해야한다.

  • 식별자는 값이 저장되어 있는 메모리 주소매핑관계. 매핑 정보도 메모리에 저장된다.
  • 이름으로 메모리 상에 존재하는 값을 식별한다. 즉, 식별자는 메모리 주소의 이름

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

식별자는 네이밍 규칙을 준수해야 하며, 선언으로 자바스크립트 엔진에 식별자의 존재를 알린다.

ex. var result = 30;

3. 변수 선언

변수 선언

  • 변수를 생성하는 것
  • 메모리 공간을 확보하고 변수 이름과 확보된 메모리 공간의 주소를 연결해 값을 저장할 수 있게 준비하는 것.
  • 확보가 해제되기 전까지 안전하게 보호된다.

변수를 사용하려면 반드시 선언이 필요하다.
var: 블록 레벨 스코프를 지원하지 않고 함수 레벨 스코프를 지원한다.
의도치 않게 전역 변수가 선언되어 부작용이 발생할 수 있다.
ES6(ES5의 상위 집합)에서 보완해서 등장한 것이 let, const
=> var let const키워드다. 자바스크립트 엔진은 키워드를 만나면 약속된 동작을 수행한다.

변수 선언과 초기화

var score;
// 선언 : 변수 이름 등록, 자바스크립트 엔진에 변수 존재 알리기
// 초기화 : 값 저장을 위한 메모리 공간 확보. 초기화가 없으면 쓰레기 값이 나올 수도 있지만 `var` 키워드를 사용한 선언에서는 자바스크립트 엔진이 암묵적으로 `undefined`(원시 타입의 값)값을 할당해 초기화한다.

변수 이름을 비롯한 식별자는 실행 컨텍스트에 등록된다.

실행 컨텍스트 : 자바스크립트 엔진이 소스코드를 평가하고 실행하기 위해 필요한 환경을 제공하고 코드 실행 결과를 실제로 관리하는 영역. 자바스크립트 엔진은 실행 컨텍스트를 통해 식별자와 스코프를 관리한다.
변수 이름과 변수 값은 / 형식인 객체로 등록되어 관리된다.

선언하지 않은 식별자에 접근하면 ReferenceError 참조 에러가 발생한다.

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

자바스크립트 코드는 인터프리터에 의해 한 줄씩 순차적으로 실행된다.
하지만 변수 선언은 런타임이 아니라 그 이전 단계에서 먼저 실행된다.

console.log(score) ; // undefined

var score; // 변수 선언문
  1. 소스코드 평가 과정 : 소스코드 실행 준비 (모든 선언문 실행)
  2. 런타임 단계 : 모든 선언문을 제외하고 소스코드를 한 줄씩 순차적으로 실행

이것을 변수 호이스팅이라고 한다.

변수 호이스팅 : 변수 선언문이 코드의 선두로 끌어 올려진 것처럼 동작하는 자바스크립트 고유의 특징

모든 식별자 var, let, const, function, function*, class 키워드로 선언하는 모든 식별자는 모두 호이스팅 된다.

5. 값의 할당

변수에 값을 할당할 때는 할당 연산자 = 를 사용해 우변의 값좌변의 변수에 할당

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

6. 값의 재할당

재할당

새로운 공간을 확보해서 저장하는 것. 저장된 값을 다른 값으로 변경한다.
var 키워드로 선언한 변수는 선언과 동시에 undefined로 초기화되므로 처음으로 값을 할당하는 것도 재할당이다.

var score = 80;
score = 90;

식별자와 연결되지 않은 (연결이 해제된) 값은 가비지 콜렉터에 의해 메모리에서 자동 해제된다. 이 시점은 예측 불가하다.
자바스크립트는 가비지 콜렉터를 내장하고 있는 매니지드 언어(언어 차원에서 메모리 관리)로서 가비지 콜렉터를 통해 메모리 누수를 방지한다.

상수

단 한 번만 할당할 수 있는 변수

값을 재할당할 수 없어서 변수에 저장된 값을 변경할 수 없다면 변수가 아니라 상수이다.

ES6에서 도입된 const키워드를 사용해 선언한 변수는 재할당이 금지된다.

7. 식별자 네이밍 규칙

규칙

  • 특수문자를 제외한 문자, 숫자, _, $
  • 숫자로 시작할 수 없다.
  • strict mode에서는 예약어를 사용할 수 없다.
  • 유니코드 문자를 허용하나, 권장하지 않는다.
  • 주석이 필요 없도록 짓자

네이밍 컨벤션

// 카멜 케이스 (변수, 함수)
var firstName;
// 파스칼 케이스 (생성자 함수, 클래스 이름)
var FirstName;
// 스네이크 케이스
var first_name;
// 헝가리언 케이스
var strFirstName

ECMAScript 사양에 정의된 객체, 함수들은 카멜/파스칼 케이스를 사용하고 있다.

profile
Frontend Web Developer

0개의 댓글