변태숙녀와 드디어 딥다이브 스터디를 시작했다.
더이상 미루면 답이 없을것같아서 일단은 숙녀분이 스터디를 하지않는 목요일에 우리의 자스 스터디를 넣기로 했다.
목요일 오후 9시 딥다이브 1강씩 가늘고 길게 보기로 했다 :)
2월 15일 첫 스타트 04장 변수 스터디 내용 기록 시자쿠
1. 변수가 왜 필요할까?
- 컴퓨터는 CPU를 사용해 연산하고, 메모리를 사용해 데이터를 기억한다.
- 메모리는 데이터를 저장할 수 있는 메모리 셀의 집합체다. 메모리 셀 하나의 크기는 1바이트(8비트)이며 컴퓨터는 메모리 셀의 크기, 즉 1바이트 단위로 데이터를 저장하거나 읽어들인다.
- 각 셀은 고유의 메모리 주소를 갖는다.
10
위 예제의 숫자값 10은 메모리상의 임의의 위치(메모리주소)에 기억(저장)되고 cpu는 이 값을 읽어들여 연산을 수행한다.
그리고 메모리에 저장되는 모든 값은 2진수로 저장된다.
하지만 메모리 주소를 통ㅎ애 값에 직접 접근하는 것은 치명적 오류를 발생시킬 가능성이 매우 높다. 실수로 운영체제가 사용중인 값을 변경하면 시스템을 멈추게 하는 치명적 오류가 발생할 수 있기때문에 자바스크립트는 개발자의 직접적인 메모리 제어를 허용하지 않는다.
그렇다면 저장된 값에 접근 하려면 어떻게 해야할까?
이때 필요한게 변수다.
변수는 하나의 값을 저장하기 위해 확보한 메모리 공간 자체 또는 그 메모리 공간을 식별하기 위해 붙인 이름을 말한다.
를 처음에 읽을땐 이해가 조금 아리송해서 주소창에 URL검색했을때 DNS서버에서 맞는 IP찾아서 데려오는 느낌으로 연상했더니 그제서야 이해가 됐다.
변수는 프로그래밍 언어의 컴파일러 또는 인터프리터에 의해 값이 저장된 메모리 공간의 주소로 치환되어 실행된다. 따라서 개발자가 직접 메모리 주소를 통해 값을 저장하고 참조할 필요가 없고 변수를 통해 안전하게 값에 접근할 수 있다.
// 변수는 하나의 값을 저장하기 위한 수단
const useId = 1;
let userName = 'Lee';
// 객체나 배열같은 자료구조를 사용해 여러 값을 하나로 그룹화해서 사용 가능
const user = { id: 1, name: 'Lee' };
const users = [
{ id: 1, name: 'Lee' },
{ id: 2, name: 'Kim' };
]
// 변수명 | 30 = 변수값
var result = 10 + 20;
마지막 예시문을 보면 10 + 20은 연산을 통해 새로운 값 30을 생성한다. 그리고 연산을 통해 생성된 값 30은 메모리 공간에 저장된다. 이때 메모리 공간에 저장된 값 30을 다시 읽어 들여 재사용할 수 있도록 값이 저장된 메모리 공간에 상징적인 이름을 붙인 것이 바로 변수다.
변수에 값을 저장하는 것을 할당(대입, 저장)이라 하고, 변수에 저장된 값을 읽어들이는 것을 참조라 한다.
2. 식별자
변수명을 또한 식별자(변수, 함수, 클래스 등의 이름)라고도 부르는데, 식별자는 값이 아니라 메모리주소를 기억하고있다. 따라서 식별자는 메모리 주소에 붙인 이름이라고 할 수 있다.
- 변수, 함수, 클래스 등의 이름과 같은 식별자는 네이밍 규칙을 준수해야한다.
- 선언에 의해 자바스크립트 엔진에 식별자의 존재를 알린다.
3. 변수 선언
변수를 사용하려면 반드시 선언이 필요하다. 변수를 사용할때는 var, let, const 키워드가 있다.
- var는 함수 레벨 스코프를 지원하고 let, const 는 블록 레벨 스코프를 지원한다.
- var는 선언과 동시에 암묵적으로 undefined 초기화를 진행한다. (초기화: 변수 선언 이후 최초로 값을 할당하는 것)
console.log(temp) // undefined
var temp ;
var temp1 ;
console.log(temp1) // undefined
/* ----------------------------------- */
console.log(tmp2) // Uncaught ReferenceError: tmp2 is not defined
let tmp2 ;
console.log(tmp2)
let tmp3 ;
console.log(tmp3) // undefined
/* ----------------------------------- */
console.log(tmp5) // Uncaught SyntaxError: Missing initializer in const declaration
const tmp5 ;
const tmp6 ;
console.log(tmp6) // Uncaught SyntaxError: Missing initializer in const declaration
console.log(tmp7) // Uncaught ReferenceError: tmp7 is not defined
const tmp7 = 8 ;
console.log(tmp7)
위의 예시를 보면 var, let, const의 콘솔 출력 결과가 다 다르다.
특히 var의 경우 선언을 하지않았는데도 에러가 나지않는다, 이유는 변수 선언이 소스코드가 한 줄씩 순차적으로 실행되는 시점, 즉 런타임이 아니라 그 이저 단계에서 먼저 실행되기 때문이다.
자바스크립트 엔진은 소스코드를 한줄씰 순차적으로 실행하기 앞서 먼저 소스코드를 평가하는 과정을 거치면서 소스코드 실행을 위한 준비를 한다. 이 소스코드 평가 과정에서 자바스크립트엔진은 모든 선언문을 소스코드에서 찾아내 먼저 실행한다. 이처럼 선언문이 코드의 선수도 끌어올려진 것처럼 동작하는 자바스크립트 고유의 특징을 호이스팅이라고 부른다.
호이스팅을 이해하고 바라보면 var는 선언과 동시에 초기화가 되어서 소스코드를 실행할때는 이미 undefined값이 할당되었기 때문에 오류가 나지않고 undefined 결과가 출력되는것이다.
let과 const의 경우 선언 이후 초기화 전까지는 TDZ라는 일시적 사각지대에 머물러져있다. 한줄씩 실행되면서 선언문을 만나면 그때 let도 undefined가 초기화되어 두번째 실행결과는 undefined가 나온다. 그러나 const의 경우는 무조건 선언을 명시해주어야 콘솔에 초기화 된 값이 출력된다. 또한 const의 경우 재할당이 금지되어 상수를 표현할 때 많이 사용한다.
4. 할당과 메모리
let tmp = 10;
temp = 20;
위 예제처럼 변수에 값을 재할당하면 변수의 값은 이전값에서 재할당한 값으로 변경된다. 변경시에는 10이 저장되어있던 메모리공간에 10을 지우고 20을 저장하는게 아닌 20이 담긴 메모리 공간에 메모리 주소를 새로 만들고 그 메모리 주소를 tmp변수가 바라보게한다. 이제 10은 불필요한 데이터이기때문에 가비지콜렉터에 의해 메모리에서 자동으로 해제된다. 하지만 메모리에서 해제되는 그 시점은 예측할 수없다. 자바스크립트같은 매니지드 언어는 메모리의 할당 및 해제를 위한 메모리 관리 기능을 언어차원에서 담당하고 개발자의 직접적인 메모리 제어를 허용하지 않기 때문이다.
생각보다 4강은 정리해야할 내용들이 많았네 ;-;
그래도 다시한번 더 짚고가는 부분들이 있어서 좋았다.
실행컨텍스트나 호이스팅은 뒤에 또 나오니까 그때보면 이해가 더 잘되겠지!
'개발 > Javascript' 카테고리의 다른 글
[Javascript] React에 Zustand와 TanStack Query 함께 사용하기 (3) | 2024.03.24 |
---|---|
[Javascript] Redux, Redux Toolkit (0) | 2024.02.27 |
[Javascript] p5js로 해머게임 만들기 (빵형의 개발도상국) (4) | 2024.01.21 |
[Javascript] history.pushState() (2) | 2024.01.02 |
[Redux-Saga & Next.js] getServerSideProps에서 dispatch 수행하기 (store.dispatch(END), store.sagaTask.toPromise()) (0) | 2023.12.21 |