[Java Script] 변수

2022. 8. 23. 23:42FE/JavaScript

변수 필요성

복잡한 애플리케이션이라도 데이터를 입력받아 처리하고 결과를 출력하는 것이 전부다.

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

 

10 + 20

컴퓨터는 연산과 기억을 수행하는 부품이 나눠져 있다.

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

 

메모리

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

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

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

메모리 주소는 0부터 시작해서 메모리 크기만큼 정수로 표현된다.

메모리 주소가 4GB라 가정하면

4GB = 1Byte x 1024 x 1024 x 1024 x 4 = 4294967296 Byte인데

 메모리 주소는 0부터 시작하므로 0 ~ 4294967295까지의 메모리 주소를 갖는다.

 

※ 하드웨어 제조회사 vs 컴퓨터에서 인식하는 메모리 크기 단위 차이

크기 하드웨어 회사 윈도우
1GB 1000MB 1024MB
1MB 1000KB 1024KB
1KB 1000B 1024B

이것이 바로 하드웨어 제조사가 표기한 메모리 크기보다 실제 윈도우에서 확인한 메모리 크기가 작은 이유다.

 

컴퓨터는 모든 데이터를 2진수로 처리한다.

따라서 메모리에 저장되는 데이터는 데이터 종류와 상관없이 모두 2진수로 저장된다.

 

메모리 주소는 16진수로 표현하면 비교적 짧게 표현할 수 있다.

4GB = 4 x $2^{10 \times 3}$ = $2^{32}$ = $2^{4 \times 8}$ → 8 자리의 16진수로 표현 가능

 

10 + 20의 연산 결과 30을 재사용하고 싶다면 메모리에 연산 결과 30을 저장하여 사용해야한다.

  0x000000F2 : 10 0x0001332 : 20   0x0669F913 : 30

메모리 주소를 통해 값에 직접 접근하는 것은 치명적 오류를 발생시킬 가능성이 매우 높다.

운영체제가 사용하고 있는 값을 변경하면 시스템을 멈출 수 있기 때문에 자바스크립트는 개발자의 직접적인 메모리 제어를 허용하지 않는다.

 

값이 저장될 메모리 주소는 코드가 실행될 때 메모리 상황에 따라 임의로 결정되는데 동일한 컴퓨터에서 동일한 코드를 실행해도 코드가 실행될 때마다 값이 저장될 메모리 주소는 변경된다.

따라서 메모리 주소를 통해 값에 직접 접근하려는 것도 좋은 방법이 아니다.

 

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

 

변수

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

→ 값을 저장하고 참조한다.

 

변수 이름은 컴파일러 또는 인터프리터에 의해 값이 저장된 메모리 공간 주소로 치환되어 실행된다.

따라서 개발자가 직접 메모리 주소를 통해 값을 저장하고 참조할 필요가 없이 변수를 통해 값에 접근할 수 있다.

 

※ 변수에 여러 개의 값을 저장하는 방법

배열이나 객체 같은 자료구조를  사용하면 관련 있는 여러 개의 값을 그룹화해서 하나의 값처럼 사용할 수 있다.

 

var result = 10 + 20;

10 + 20 연산 결과가 저장된 메모리 주소를 식별하는 게 바로 변수다.

 

변수에 값을 저장하는 것을 할당 or 대입이라 하고 변수에 저장된 값을 읽어 들이는 것을 참조라 한다.

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

 

식별자

변수 이름을 식별자라고도 한다.

변수는 메모리 공간에 저장되어 있는 어떤 값을 구별해서 식별해낼 수 있어야한다.

따라서 변수는 값을 저장하는 것이 아니라 값이 저장되어 있는 메모리 주소를 기억하고 있다.

 

식별자는 변수뿐만 아니라 함수, 클래스 등 모두 해당된다.

식별자는 선언에 의해 자바스크립트 엔진에 식별자 존재를 알린다.

 

변수 선언

변수를 생성하는 것을 말한다.

값을 저장하기 위한 메모리 공간을 확보하고 변수 이름과 확보된 메모리 공간의 주소를 연결해서 값을 저장할 수 있게 준비한다.

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

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

ES6에서 let, const 키워드 도입 전 변수 선언할 수 있는 유일한 키워드는 var이었다.

 

※ var 키워드 단점

block-level scope를 지원하지 않고 function-level scope를 지원한다.

이로 인해 의도치 않게 전역 변수가 선언되어 버그 발생할 수 있다.

 

※ 키워드

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

자바스크립트 엔진은 키워드를 만나면 자신이 수행해야 할 약속된 동작을 수행한다.

 

var score;

var 키워드는 변수 선언만 하고 값을 할당하지 않았지만 자바스크립트 엔진에 의해 undefined라는 값으로 초기화된다.

 

※ undefined는 자바스크립트에서 제공하는 원시 타입 값이다.

 

※ 변수 이름은 어디에 등록될까?

변수 이름을 포함한 모든 식별자는 실행 컨텍스트에 등록된다.

execution context는 자바스크립트 엔진이 소스코드를 평가하고 실행하기 위해 필요한 환경을 제공하고 코드의 실행 결과를 실제로 관리하는 영역이다. 자바스크립트 엔진은 execution context를 통해 식별자와 스코프를 관리한다.

변수 이름과 값은 실행 컨텍스트 내에 key/value 형식인 객체로 등록되어 관리된다.

 

※ ReferenceError

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

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

 

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

console.log(score);
var socore;

변수 선언문보다 변수를 참조하는 코드가 앞에 있다.

자바스크립트 코드는 인터프리터에 의해 한 줄씩 순차적으로 실행되므로 참조 시점에 score 변수가 선언이 실행되지 않았기 때문에 ReferenceError가 발생할 것 같지만 undefined가 출력된다.

 

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

 

자바스크립트 엔진은 소스코드를 한 줄씩 실행하기 전에 먼저 소스코드 평가 과정을 거쳐 소스코드를 실행하기 위한 준비를 한다. 소스코드 평가 과정에서 자바스크립트 엔진은 변수 선언을 포함한 모든 선언문을 소스코드에서 찾아 먼저 실행한다. 소스코드 평가 과정이 끝나면 모든 선언문을 제외하고 소스코드를 한 줄씩 순차적으로 실행한다.

 

 

호이스팅

선언문이 코드의 선두로 올려진 것처럼 동작하는 자바스크립트 특징

var, let, const, function, function*, class 키워드 등 선언문이 런타임 이전에 실행된다.

 

값 할당

변수에 값을 할당할 때 대입 연산자 = 를 사용한다.

var score;
score = 100;

변수 선언 후 최초로 값을 할당하는 것을 초기화라 한다.

var score = 100;

변수 선언과 값을 할당하는 코드를 합쳐서 표현할 수 있다.

그러나 자바스크립트 엔진은 변수 선언과 할당을 2개의 문으로 나누어 각각 실행한다.

score 변수에 undefined가 할당되고 그 이후 100이 할당된다.

 

               score

0x000000F2

undefined
       

 

                                                                                            score

0x000000F2

undefined
  0x0001332

100
   

 

변수에 값이 할당할 때 이전 값 undefined가 저장되어 있던 메모리 공간을 지우고 그 메모리 공간에 할당 값을 새롭게 저장하는 것이 아니다. 새로운 메모리 공간을 확보하고 그곳에 값을 저장한다.

 

값 재할당

var 키워드로 선언한 변수는 값을 재할당할 수 있다.

변수의 값이 재할당되면 이전 메모리 공간은 어떤 식별자도 연결되어 있지 않기 때문에 불필요한 메모리 공간이다.

이러한 메모리 공간은 가비지 컬렉터에 의해 메모리에서 자동 해제된다.

 

※ const 키워드

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

const 키워드를 사용하면 상수로 표현할 수 있다.

 

※ 가비지 컬렉터

애플리케이션이 할당한 메모리 공간을 주기적으로 검사하여 더 이상 사용되지 않는 메모리를 해제하는 기능을 말한다.

어떤 식별자도 참조하지 않는 메모리 공간을 해제한다.

가비지 컬렉터를 통해 메모리 누수를 방지한다.

 

※ unmanagaed 언어 vs managed 언어

프로그래밍 언어는 메모리 관리 방식에 따라 두 언어로 분류할 수 있다.

C 언어와 같은 언매니지드 언어는 개발자가 명시적으로 메모리를 할당하고 해제하기 위해 malloc()과 free() 같은 저수준 메모리 제어 기능을 제공한다.

자바스크립트 같은 매니지드 언어는 메모리 할당 및 해제를 위한 메모리 관리 기능을 언어 차원에서 담당하고 있어 개발자가 메모리 제어를 허용하지 않는다. 생산성을 확보할 수 있는 장점이 있지만 성능 면에서 어느 정도 손실도 있다.

 

식별자 네이밍 규칙

식별자는 특수문자를 제외한 문자, 숫자, 언더스코어_, 달러 기호$를 포함할 수 있다.

단 식별자는 특수문자를 제외한 문자, _, $ 로 시작해야 한다. 숫자로 시작할 수 없다.

예약어는 식별자로 사용할 수 없다.

 

※ 예약어

await, break, case, catch, class, const, continue, debugger, default, delete, do,else,enum,export, extends, false, finally, for, function, if, implements*, import, in, instanceof, interface*, let*, new, null, package*, private*,protected*,public*, return, super, static*, swtich, this, throw, true, try, typeof, var, void, while, with, yield*

*로 표시된 예약어는 식별자로 사용가능하나 strict mode에서는 사용 불가 (엄격하게 문법 검사)

 

참고로 변수는 , 로 구분하여 하나의 문에서 여러 개를 한 번에 선언할 수 있다.

var a, b, c, d, e;

ES5부터 식별자를 만들 때 유니코드 문자를 허용하므로 알파벳 외의 한글 식별자도 사용할 수 있지만 권장하지 않음

자바스크립트는 대소문자를 구별한다.

 

네이밍 컨벤션

일반적으로 변수나 함수 이름은 카멜 케이스를 사용하고 생성자 함수, 클래스 이름은 파스칼 케이스를 사용한다.

// 카멜 케이스
var firstName;

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

// 파스칼 케이스
var FirstName;

 

728x90

'FE > JavaScript' 카테고리의 다른 글

[Java Script] 데이터 타입  (0) 2022.08.24
[Java Script] 표현식  (0) 2022.08.24
[Javascript] 자바스크립트 실행환경  (0) 2022.08.23
[Javascript] 자바스크립트란  (0) 2022.08.23
[Java Script] 자바스크립트 기초  (0) 2022.08.18