Notice
Recent Posts
Recent Comments
Link
«   2025/03   »
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31
Archives
Today
Total
관리 메뉴

과거의 내가 미래의 나에게

딥다이브 :: 변수 & 표현식과 문(state) 본문

js 이론

딥다이브 :: 변수 & 표현식과 문(state)

양바삭 2022. 12. 28. 01:03

「딥다이브 자바스크립트」 정리 - 변수 & 표현식과 문

※ 아래 내용은 책을 통해 학습한 것을 개인적으로 정리한 것으로 내용이 다소 부정확 할 수 있습니다.

 

 


1. 변수

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

메모리란?

메모리는 데이터를 저장하는 메모리 셀의 집합체이다. 메모리 셀 하나의 크기는 1바이트로, 컴퓨터는 메모리 셀 하나의 크기 단위로 저장하거나 읽는다. 예를 들어, 1 + 2를 계산한다면 메모리 셀 하나에 1이 저장되고, 또 다른 메모리 셀에는 2가 저장된다. 그리고 CPU는 1과 2를 꺼내어 연산하고 그 결과값인 3을 또다른 메모리 셀에 저장하는 식이다.

각 셀은 고유의 메모리 주소를 가지는데 이는 메모리의 위치를 나타내는데 쓰인다. 이 주소는 0부터 시작해서 메모리 크기만큼 정수로 표현된다. 

메모리 주소의 활용

메모리에 값을 넣고 이를 다시 꺼내 쓰고 싶을 때, 메모리에 직접적으로 접근한다면 매우 위험하다. 만약 실수로 운영체제가 사용하고 있는 값을 변경해버리거나 하면 치명적일 수도 있을 테니 말이다. 그러므로 js는 직접적으로 메모리에 다가가지 않는다.

< 참조 >
개발자가 직접적으로 메모리에 접근하고 제어할 수 있는 언어를 managed 언어라 하며 대표적으로 C언어가 있다.
반대로 개발자가 직접 메모리에 접근하는 것을 허용하지 않은 언어는 unmanaged 언어라 하며 여기에는 js가 있다.

그렇다면 넣어둔 값을 재사용하고 싶을 때는 어떻게 할까? 이 때 변수라는 메커니즘을 활용하게 된다. 변수는 하나의 값이 메모리셀에 저장될 때 그 위치를 파악할 수 있도록 별도로 붙인 이름이다. 변수 이름을 사용하면 저장된 값이 아니라 그 값이 저장된 메모리 공간의 주소로 치환되어서 값을 활용할 수 있게 한다. 즉, 값은 메모리 공간에 저장되어 있고, 변수는 이 값이 저장되어있는 메모리 주소를 기억한다. 

함수나 클래스 등의 이름도 모두 변수처럼 메모리 주소를 식별할 수 있는 이름인데, 마찬가지로 이를 통해 메모리 상에 존재하는 함수나 클래스를 식별 할 수 있다.(js에서는 함수도 값이란다)

 

변수나 함수와 같은 식별자는 네이밍 규칙을 준수해야하며, 선언을 통해 js엔진에 식별자의 존재를 알린다.

< 변수의 네이밍 규칙 >
▶ 첫 번 째 글자는 문자, '$', '_' 이어야 한다.
▶ 두 번 째 이후의 글자는 문자, 숫자, '$', '_' 이여야 한다.
▶ '$', '_' 이외의 특수 문자는 사용 할 수 없다.
▶ 예약어는 사용할 수 없다.
▶ 하나 이상의 글자로 이루어져야하며 길이의 제한은 없다.
 < 항상 헛갈리는 네이밍 컨벤션 >

스네이크케이스: first_name

카멜케이스: firstName

파스칼케이스: FirstName

 케밥케이스: first-name

변수의 선언 및 호이스팅

변수의 선언은 var, let, const 를 사용하며(셋의 차이는 추후에 다룰 것이다) 변수를 선언하면 메모리 공간이 확보되고, 확보된 공간의 주소가 연결된다.

변수는 다음과 같은 두 가지 과정을 거친다. 

  1. 선언 단계: 변수 이름을 등록해서 js 엔진에 변수의 존재를 알린다.
  2. 초기화단계: 메모리 공간 확보 및 암묵적으로 undefined를 할당하여 초기화한다.

var의 경우 선언단계와 초기화단계가 동시에 진행된다. 이로 인해 var는 선언과 동시에 undefined로 초기화함으로 메모리 공간에 이전에 사용했던 값이 남아 있거나 하는 위험은 없다.

 

변수 선언은 소스 코드가 한 줄씩 순차적으로 실행되는, 런타임 이전에 먼저 실행된다. 런타임이 진행되기 이전에 모든 선언문을 소스코드에서 찾아내 실행하며 그 후 선언문 제외한 나머지 소스코드들을 순차실행한다. 이와 같이 선언문이 코드의 제일 앞으로 끌어 올려진 것을 변수 호이스팅이라 한다.

값의 할당과 재할당

변수에 값을 저장하는 것을 할당이라 하고(저장된 값을 읽는 것은 참조라 한다) 값의 할당의 실행 시점은 런타임 이후다.

값을 재할당하면 재할당 전의 값이 저장되어있던 메모리에다 하는 것이 아닌 새로운 메모리 공간에 저장한다. 그러므로 var 변수 선언 시 undefined이 메모리에 할당되고, 후에 값을 할당하면 undefined가 들어가있는 메모리에 다시 재할당되는게 아니라 다른 메모리에 할당된다.(변수의 선언과 값의 할당은 하나의 문으로 써도 js엔진은 각각 2개의 문으로 실행한다.)

재할당으로 인해 변수와 해제 된 이전 메모리의 값은 어떤 식별자도 가지고 있지 않기 때문에 더이상 쓰이지않고, 이런 값들은 가비지 콜렉터에 의해 자동 해제된다(언제 해제되는지는 알 수 없다.)

// 다음 console.log에 찍히는 값은?

console.log(score) //undefined
score = 80 // 런타임 후 순차적으로 실행
var score // 런타임 전 실행(호이스팅)
console.log(score) //80

 

변수의 생명 주기

변수는 생성되고 소멸되는 생명 주기가 있다. 생명 주기가 없다면 변수는 한 번 선언되고 프로그램이 종료되지 않는 이상 영원히 메모리 공간을 점유하게 된다.

 

1. 지역 변수의 생명 주기

함수 내부에서 선언된 지역 변수는 함수가 호출되면 생성되고, 함수가 종료되면 소멸한다.

변수 호이스팅은 엄연히 말하면 전역 변수에서만 해당되는 이야기이다. 지역 변수는 함수가 호출되면, 함수 내에 다른 문들이 순차적으로 실행되기 이전에 변수의 선언문이 js 엔진에 의해 가장 먼저 실행되어 변수가 선언되고 undefined로 초기화된다. 즉, 호이스팅은 스코프를 단위로 동작하는 것이다. 그 후 다른 문들이 순차적으로 실행되고 그리고 함수가 종료되면 변수도 소멸되어 생명 주기가 종료된다. 따라서, 지역 변수의 생명주기는 함수의 생명 주기와 일치한다.

그러나 지역 변수가 함수보다 오래 생존하는 경우도 있다. 함수 내부에서 선언된 지역 변수는 함수가 생성한 스코프에 등록된다. 함수가 생성된 스코프는 렉시컬 환경이라 부르는 물리적인 실체가 있는데, 변수는 자신이 등록된 스코프가 소멸될 때까지 유효하다. 즉, 누군가 메모리 공간을 참조하고 있으면 소멸되지 않은채로 남아 있게 된다. 일반적으로 함수가 종료하면 함수가 생성한 스코프도 소멸하지만 누군가가 스코프를 참조하고 있다면 생존하게 된다.

 

2. 전역 변수의 생명 주기

var 키워드로 선언한 전역 변수는 전역 객체의 프로퍼티가 된다. 이는 전역 객체와 전역 변수의 생명주기가 일치한다는 것을 말한다. 전역 객체(클라이언트 환경 기준)는 웹페이지를 닫기 전까지 유효함으로 따라서 var 키워드로 선언한 전역 변수 역시 웹페이지를 닫을 때까지 유효하다.

< 전역 객체 >
전역 객체는 코드 실행 이전에 js 엔진에 의해 가장 먼저 생성되는 특수한 객체다. 이는 브라우저에서는 window, node에서는 global 객체를 의미한다. 전역 객체는 표준 빌트인 객체, 환경에 따른 호스트 객체, var 키워드로 선언한 전역 변수와 전역 함수를 프로퍼티로 갖는다.

2. 표현식과 문

값은 표현식이 평가(식을 해석해서 값을 생성하거나 참조하는 것)되어 생성된 결과를 말한다.

메모리에 저장된 값은 데이터 타입에 따라 다르게 해석될 수 있다. 예를 들어 한 데이터 값을 숫자로 해석하면 65지만, 문자로 해석하면 A가 될 수도 있다.

값을 생성하는 방법

1. 표현식

표현식은 값으로 평가될 수 있는 문(state)이다. 표현식이 평가되면 새로운 값을 생성하거나 기존 값을 참조한다. 값으로 평가될 수 있으면 모두 표현식이라 부른다. 즉, 해석해서 값이 나오면 이는 표현식이라 한다.

< 리터럴 >
리터럴은 사람이 이해할 수 있는 문자 또는 약속된 기호로 표기한 코드이다. 런타임 시점에 리터럴을 평가하여 값을 생성한다. 이는 값을 생성하기 위해 미리 약속한 표기법. 리터럴 또한 표현식이다.

2. 문(state)

문은 프로그램 구성의 기본 단위이고 최소 실행단위이다. 명령문이라고도 부르고, 이는 선언문 할당문 조건문 등으로 구분 가능하다. 문은 여러 토큰(문법적으로 더이상 나눌 수 없는 기본요소)으로 구성된다.

< 크롬 개발자 도구에서의 표현식  >

크롬 개발자 도구에서 표현식이 아닌 문(값으로 평가될 수 없는 문)을 실행하면 undefined로 출력한다. 이를 완료 값이라 하며 완료값은 평가 결과가 아니기에 변수에 할당할 수도 없고 참조할 수도 없다.

표현식인 문을 쓰면 평가된 값을 반환한다!

 

 

Comments