자바스크립트 딥다이브 - 변수

ChoiYongHyeun·2023년 12월 6일
0

변수

var result = 10 + 20;
console.log(result);

해당 코드에서 10 + 20 이라는 값을 result 라는 변수에 담아주었다.

변수에 값을 담는 다는 것은 무엇이고, 변수의 의미는 무엇일까 ?

컴퓨터가 10 + 20 이라는 값을 인식하기 위해서는 10, 20, + 라는 기호 (literaloperator) 의 의미를 알고 있어야 하며 10 + 20 이라는 식을 해석 (parsing) 할 수 있어야 한다.

자바 스크립트 엔진이 10 + 20이라는 식의 의미를 해석하면 + 연산자와 10, 20 피연산자를 기억한다.

컴퓨터는 CPU 를 사용해 연산하고, 메모리를 사용해 데이터를 기억한다.

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

각 메모리 셀은 고유의 메모리 주소를 가진다.

위 예제에서 두 피연산자인 10, 20 은 임의의 위치 (메모리 주소) 에 기억되고 CPU 는 이 값을 받아들여 연산을 수행한다.

연산의 결과값인 30 도 임의의 위치에 저장된다.

만약 결과값을 변수에 저장하지 않고

10 + 20

만 사용한다면 결과값은 메모리에 저장되지만 재사용 할 수 없다.

그 이유는 임의로 저장된 결과값인 30 이 저장되어 있는 메모리 주소를 참조하는 것 외에는 방법이 없기 때문이다.

하지만 메모리 주소를 통해 값에 직접 접근하는 것은 치명적인 오류를 발생 시킬 수 있다.

값이 저장 될 메모리 주소는 메모리 상황에 따라 임의로 변경되기 때문
그로인해 잘못된 메모리 주소를 참조하여 값을 변경하거나 저장하면 치명적인 오류 발생

var result = 10 + 20;
console.log(result);

에서 result는 결과값을 담는 변수 의 역할을 하고 있다.

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

간단히 말하면 값의 위치를 가리키는 상징적인 이름 을 의미한다.

여기서 result 는 결과값이 담긴 변수의 이름이기에 변수 이름 , 변수명 이라고 하며 안에 저장된 값인 30은 변수 값 이라고 한다.

변수 이름은 사람을 위해 사람이 이해 할 수 있는 언어로 값이 저장된 메모리 공간에 붙인 상징적인 이름이며, 자바스크립트 엔진은 변수 이름과 매핑된 메모리 주소를 통해 메모리 공간에 접근해서 저장된 값을 반환한다.

식별자

변수 이름을 식별자(identifier) 라고 한다.

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

var result = 10 + 20;
console.log(result);

10 + 20 의 결과값이 임의의 메모리에 맵핑 -> result 라는 변수는 결과값 메모리 주소를 담음

이런 식으로 될 때 result10+20 의 연산 결과를 담은 식별자 이면서 결과 값이 담긴 메모리 주소 를 기억하고 있다.

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

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

변수 선언

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

변수 선언에 의해 확보된 메모리 공간은 확보가 해제되기 전까지는 누구도 확보된 메모리 공간을 사용 할 수 없도록 보호되므로 안전하게 사용 가능하다.

변수를 사용하려면 반드시 선언이 필요하다.

  • var
  • let
  • const

키워드를 이용한다.

var score; // 변수 선언 (변수 선언문)
console.log(score);

var 키워드를 이용해 변수 이름을 등록하고 값을 저장할 메모리 공간을 확보한다.

키워드

키워드는 자바스크립트 코드를 해석하고 실행하는 자바스크립트 엔진이 수행할 동작을 규정한 일종의 명령

score 값에 어떤 값도 저장하지 않았기 때문에 메모리에는 원시 타입의 값인 undefined
가 저장되어 있다.

자바 스크립트 엔진은 변수 선언을 2단계에 거쳐 수행한다.

  1. 선언 단계 : 키워드와 변수명을 이용해 자바스크립트 엔진에 변수의 존재를 알림
  2. 초기화 돤계 : 값을 저장하기 위해 메모리 공간으 확보하고 암묵적으로 원시 타입의 값인 undefined 를 할당해 초기화

초기화는 확보된 메모리 공간에 이전에 사용한 다른 애플리케이션의 값이 남아 있을 수 있다. 이를 쓰레기값 garbage value 라고 하는데, 이를 undefined 로 변경하여 메모리 공간을 확보한 다.

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

console.log(score);

var score;

만약 다음처럼 score 를 먼저 호출 시키고 score 의 값을 지정해준다면

참조 에러 (ReferenceError) 가 발생할 것처럼 보이지만 참조에러가 발생하지 않고 undefined 가 잘 출력된다.

그 이유는 변수 선언이 소스코드가 한 줄씩 순차적으로 실행되는 시점, 즉 런타임이 아니라 그 이전단계에서 먼저 실행되기 때문이다.

자바스크립트 엔진은 소스코드를 한줄씩 순차적으로 실행하기 앞서 소스코드 평가 과정을 거치면서 소스코드를 실행하기 위한 준비를 한다.

평가 과정에서 변수 선언을 포함한 모든 선언문을 소스코드에서 찾아내 먼저 실행한다.

평가 과정이 끝나면 비로소 변수 선언을 포함한 모든 선언문을 제외하고 소스코드를 한줄씩 순차적으로 실행한다.

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

값의 할당

변수에 값을 할당(assignment)할 때는 할당 연산자 = 를 사용한다.

var score;
score = 1

var score = 1

변수를 선언하고 할당해줘도 되고, 할당과 선언을 하나의 문으로 단축 표현할 수도 있다.

console.log(score);
var score = 1;
console.log(score);

만약 이렇게 하면 결과값이 어떻게 나올까 ?

undefined
1

이렇게 나온다.

호이스팅은 메모리 값에 공간만 남기고, 초기화만 해둔다.

할당은 안한다.

그런 할당은 undefined 가 print 된 후에 1이 할당된다

다만 변수를 선언하고 할당하게 되면 선언한 메모리 셀에 값을 할당하는 것이 아니라

선언된 자리는 undefined 로 남고, 다른 메모리 셀에 값이 할당된다. (이 때 똑같이 공간을 확보하고 값을 할당한다.)

값의 재할당

var score = 80;
score = 90;
console.log(score);

다음처럼 score변수에 80을 설정했다가 90의 값을 재할당 할 수도 있다.

재할당은 변수에 저장된 값을 변경한다.

처음 var score = 80 이 실행 될 때 맨 처음 선언과 초기화로 인해 O 라는 주소에 undefined 값이 담기며 초기화가 된다.

이후 score = 80; 이 실행되며 score 라는 식별자에 80값의 주소가 담기게 된다.

score 를 위한 메모리 주소를 A 라고 뒀을 때 A 라는 값에 80 을 저장하고 A 의 주소를 score에 담는다.

이후 score = 90 이라고 하면 B 라는 주소에 90 을 담고 B 의 주소를 score 식별자에 담는다.

(총 3개의 메모리 셀이 사용되며 옮겨갔을 것이다.)

만약 값을 재할당 할수 없어서 변수에 저장된 값을 변경 할 수 없다면 이를 변수가 아닌 상수(constant) 라고 한다.

const foo = 10;
foo = 100;
TypeError: Assignment to constant variable.

상수에는 값을 재할당 할 수 없다.

그렇다면 O , A 는 어떻게 될까 ? 더이상 어떤 식별자도 해당 메모리셀을 참조하고 있지 않는데
이는 더이상 필요하지 않기 때문에 가비지 콜렉터에 의해 메모리에서 자동 해제된다.

단 메모리에서 언제 해제될지는 예측 할 수 없다.

가비지 콜렉터

어떤 식별자도 참조하지 않는 메모리를 해제하는 기능으로서, 자바스크립트는 가비지 콜렉터를 내장하고 있는 매니지드 언어로 메모리 누수를 방지한다.

언 매니지드 언어와 매니지드 언어

C 언어와 같은 언매니지드 언어는 명시적으로 메모리를 할당하고 해제해줘야 한다.
언매니지드 언어는 메모리 제어를 개발자의 역량에 따라 최적의 성능을 확보할 수 있지만 잘못 제어 한다면 치명적 오류를 발생 시킬 수 있음
매니지드 언어는 개발자가 직접 메모리를 제어 할 수 없으나 가비지 콜렉터가 메모리 관리를 자동으로 해준다.

네이밍 규칙

// 카멜 케이스
var firstName;

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

// 파스칼 케이스
var FirstName;

// 헝가리언 케이스

var strFirstName;
var $elem = document.getElementById('myId');

등 다양한 네이밍 규칙이 존재하지만

자바스크립트에선 일반적으로 변수나 함수의 이름에는 카멜 케이스 를 사용하고 생성자 함수, 클래스 이름에는 파스칼 케이스를 사용한다.

따라서 코드 전체의 가독성을 높이려면 카멜 케이스와 파스칼 케이스를 따르는 것이 유리하다.

profile
빨리 가는 유일한 방법은 제대로 가는 것이다

0개의 댓글