[모던 자바스크립트 딥다이브] 04장 변수

Narcoker·2022년 9월 18일
0

✏️변수란 무엇인가? 왜 필요한가

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

모든 애플리케이션은 데이터를 입력받아 처리한 결과를 출력한다.

10 + 1

이라는 식을 입력했다고 가정해보면
피연산자 10, 1은 메모리에 2진수로 저장된다.

CPU는 이 값을 읽어와 연산하고 결과값을 메모리상의 임의의 위치에 저장한다.
만약 이 결과 값인 30을 재사용하고 싶다면 이 값이 저장된 메모리 공간에
직접 접근하는 것 말고는 방법이 없다.

만약, 실수로 운영체제가 사용하는 값이 저장된 메모리에 접근하여
값을 변경하게 된다면 치명적인 오류가 발생할 수 있다.
따라서 자바스크립트는 개발자의 직접적인 메모리 제어를 허용하지 않는다.

자바스크립트가 허용한다고 하더라도 값을 저장할 메모리 주소는
상황에 따라 임의로 결정된다.
따라서 메모리 주소를 통해 값에 접근하는 것은 올바른 방법이 아니다.

✏️식별자

식별자는 어떤 값을 구별해서 식별할 수 있는 고유한 이름을 말한다.
변수 이름을 식별자(identifier) 라고도 한다.
식별자는 값이 아니라 메모리 주소를 기억한다.

var result = 30;

위 코드에서 식별자 result 는 값 30을 식별할 수 있으며
식별자 result는 값 30이 저장되어 있는 메모리 주소를 기억해야한다.
즉 식별자는 값이 저장되어있는 메모리주소와 매핑 관계를 맺으며
이 정보도 메모리에 저장한다.

✏️변수 선언

변수를 생성하는 것을 의미한다.
변수를 사용하려면 반드시 필요하다.
값을 저장하기 위한 메모리 공간을 확보하고
변수 이름과 확보된 메모리 공간을 매핑 하는 과정을 의미한다.

선언하지 않고 변수를 사용하면 ReferenceError(참조 에러) 가 발생한다.
ReferenceError란 식별자를 통해 값을 참조하려 했으나 찾을 수 없는 경우 발생한다.

실행 컨텍스트

자바스크립트 엔진이 소스 코드를 평가하고 실행하기 위한 환경을 제공하고
코드의 실행 결과를 실제로 관리하는 영역이다.

변수 이름을 비롯한 모든 식별자는 실행 컨텍스트에 객체 형식으로 등록된다.

변수 선언 2단계

  • 선언 단계
    - 변수 이름을 등록해서 자바스크립트 엔진에 변수 존재를 알림
  • 초기화 단계
    - 값을 저장하기 위한 메모리 공간을 확보하고 undefined를 할당해 초기화

만약 초기화 단계를 처지지 않으면 확보된 메모리 공간에는
이전 애플리케이션이 사용했던 값이 남아 있을 수 있는데
이러한 값을 쓰레기 값이라 한다.

var 키워드는 암묵적으로 초기화를 수행하므로 이런한 위험으로 부터 안전하다.

키워드

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

ex) var 키워드를 만나면 해당 변수 이름으로 새로운 변수를 선언

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

console.log(score);
var score;

위 코드는 인터프리터 구조 상 score 변수를 선언전에 사용 했으므로
ReferenceError를 발생시킬 것으로 예상되지만 그렇지 않다.

이유는 변수 선언 시점이 코드 실행 시점(런타임) 이 아니라
그 이전 단계에서 먼저 실행되기 때문이다.

자바스크립트 엔진은 런타임 이전에 소스코드 평가 과정을 거친다.
이때 변수 선언을 포함한 모든 선언문(변수, 함수 선언문 등)을 소스코드에서 찾아
먼저 실행한다. 이를 호이스팅이라한다.

즉, 자바스크립트 엔진은 변수 선언이 소스코드에 어디에 있든 상관없이
다른 코드보다 먼저 실행하기 대문에 어디에서든지 변수를 참조할 수 있다.

var, let, const, funciton function*, class 키워드를 사용해서
선언하는 모든 식별자는 호이스팅된다.

✏️값의 할당

값의 할당은 할당 연산자 = 을 사용한다.

var score;
score = 30; 
// 또는
var score = 30;

위 두 코드는 정확하게 동일하게 동작한다.

변수 선언은 런타임 이전에 실행되고 값의 할당은 런타임에 실행된다.

console.log(score); // undefined
var score = 30; // 30 할당
console.log(score); //  30

주의

위 코드 처럼 변수에 값을 할당할때는 이전 값 undefined가 저장되어있던 메모리 공간을 지우고 메모리 공간에 할당 값 30을 저장하는 것이 아니라 새로운 메모리 공간을 확보하고 할당값 30을 저장한다.

✏️값의 재할당

이미 값이 할당되어 있는 변수에 새로운 값을 또다시 할당하는 것을 의미한다.

var 키워드로 선언한 변수 값은 재할당할 수 있다.
사실상 var 변수는 선언과 동시에 undefined로 초기화 되기 때문에
엄밀히 말하자면 처음 할당하는 것도 재할당이다.

만약 값을 재할당 할 수 없어서 변수에 저장된 값을 변경할 수 없다면
이는 변수가 아니라 상수이다.
상수는 한 번만 할당할 수 있는 변수다.
상수는 const로 선언한다.

const 키워드는 반드시 상수만을 위해 사용하지는 않는다. 15장: const 키워드

변수에 값을 재할당하면 score 변수의 값은 처음 할당 했을 때와 마찬가지로
이전 메모리 공간을 지우고 그 메모리 공간에 새로운 값을 저장하는 것이 아니라
새로운 메모리 공간을 확보하고 그 메모리 공간에 새 값을 저장한다.

현재 num 값은 90이다. 사용되지 않는 80과 undefined는
어떤 식별자와도 연결되어 있지 않다.
더 이상 필요하지 않은 값들은 가비지 콜렉터에 의해 메모리에서 자동 해제 된다.
단, 메모리에서 언제 해제될지는 예측할 수 없다.

가비지 콜렉터

애플리켕션이 할당한 메모리 공간을 주기적으로 검사하여 더 이상 사용되지 않는
메모리를 해제하는 기능을 말한다.
즉, 어떠한 식별자도 참조하지 않는 공간을 해제하는 기능이다.

자바스크립트는 가비지 콜렉터를 내장하고 있는 매니지드 언어로서,
가비지 콜렉터를 통해 메모리 누수를 방지한다.

🔴자바스크립트에서 StringBuilder() 같은 클래스가 없는 이유

문자열 재할당 방법에는 += 를 사용하는 방법과
배열에 push() 후 join() 하는 법이 있다.
선자의 경우 메모리를 많이 잡아먹을 것으로 예상하여 자바의 StringBuilder()
같은게 있어야 할 것 같지만,
실제로 자바스크립트 엔진에서 += 가 최적화(Rope 데이터 구조 사용)가 잘 되어있어서 필요가 없다고한다.

2^27 의 연산 내에서는 Rope 데이터 구조에서 충분하기 때문이다.
이 이상으로 어떤 작업을 할 때는
StringBuilder()와 유사한 것을 사용하는 것이 더 나을 수도 있다.

언매니지드 언어 vs 매니지드 언어

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

C언어는 언매니지드 언어이다.
개발자가 명시적으로 메모리를 할당하고 해제하기위해 malloc()과 free() rkxdms
저수준 메모리 제어 기능을 제공한다.
메모리를 개발자가 주도할 수 있으므로 개발자의 역량에 따라
최적의 성능을 확보할 수 있지만, 아닌 경우 치명적인 오류를 발생시킬 수 있다.

자바스크립트는 매니지드 언어이다.
개발자의 직접적인 메모리 제어를 허용하지 않는다.
더 이상 사용하지 않는 메모리 해제는 가비지 콜렉터가 수행하며,
이 또한 개발자가 관여할 수 없다.
일정한 생산성을 확보할 수 있지만 성능면에서 어느 정도 감수해야만 한다.

✏️식별자 네이밍 규칙

  • 식별자는 특수문자를 제외한 문자, 숫자, 언더스코어(_), 달러 기호($)를 포함할 수 있다.
  • 단 식별자는 특수 문자를 제외한 문자, 언더스코어(_), 달러 기호($)로 시작해야한다.
  • 숫자로 시작할 수 없다.
  • 예약어는 식별자로 사용할 수 없다.
  • 대소문자를 구분한다.
  • 변수의 이름은 변수의 존재 목적을 쉽게 이해할 수 있도록 의미를 명확히 한다.
    - 주석이 필요하다면 실패한 네이밍이다.
  • 변수는 쉼표로 구분해 하나의 문에서 여러 개를 한번에 선언할 수 있지만 가독성이 떨어져서 권장하지 않음
  • 유니코드 문자를 허용하나 권장하지 않음

예약어

프로그래밍 언어에서 사용되고 있거나 사용될 예정인 단어를 말한다.

네이밍 컨벤션

하나 이상의 영어 단어로 구성된 식별자를 만들 때
가독성 좋게 단어를 한눈에 구분하기 위해 명명한 규칙이다.

변수나 함수 이름은 카멜 케이스,
생성자 함수, 클래스 이름은 파스칼 케이스를 사용하는 것을 권장한다.

  • 카멜 케이스
var firstName;
  • 스네이크 케이스
var first_name;
  • 파스칼 케이스
var FirstName
  • 헝가리안 케이스
var strFirstName; // type+identifier
var $elem = document.getElementById('myId'); // DOM 노드
var observable$ = fromEvent(document, 'click'); // RxJS 옵저버블
profile
열정, 끈기, 집념의 Frontend Developer

0개의 댓글