[Study] Deep Dive - 변수, 호이스팅

M_yeon·2023년 3월 8일
0

Deep Dive

목록 보기
1/6
post-thumbnail

스터디를 구하던 중 모르는 사람들과 있으면 기가 빨리는 편이고,
이것저것 신경쓸게 많아서 원래 같이 공부하던 마음맞는 친구들과 스터디를 하고자 했다.

협업툴 : 노션, Slack
주제: 모던 자바스크립트 딥 다이브 중심으로 한 JS 완벽 다지기
JS를 뿌시고 CS를 들어가려 한다.


연산은 CPU, 기억은 메모리가 한다
변수 : 변수는 데이터를 저장하기 위한 메모리 공간을 !참조!하는 이름입니다.

10 + 20을 해줘! 라고 해보자
그러면 컴퓨터는 10, 20, 결과값인 30, 심지어 + 까지 파싱(Read)할 수 있어야한다.
그럼 이 결과값인 30은 한번 요청받고 30을 되돌려주면 끝이다.

어! 나는 이 값을 여러번 사용할거야~ 계속해서 꺼내서 쓸 수는 없을까?

이러한 생각으로 우리는 변수를 만들어낸다!
그런데 30을 할당했던 변수를 없애고 새로운 변수명에 30을 할당하면 그 메모리를 재사용한다고 한다.

var, let, const를 사용해서 변수에 값을 할당하고 변수값을 읽어 들이는 것을 참조라고 한다.

우선 자바스크립트는 메모리주소에 직접 접근할 수 없다.(메모리주소는 정적이지 않다.)
이유는 개발자가 메모리주소에 직접 접근을 했다가는 운영체제에 문제가 생길것!

변수에 값을 할당했을때 메모리가 그 값을 기억하고 있을것이고,
변수는 메모리 주소를 따라다니기 때문에 변수 -> 메모리주소-> 메모리(값: 30)
이런식으로 접근을 한다는것이다.

대부분 다 아시다시피 var의 단점 중 가장 대표적인것

1. 블록 레벨 스코프 지원 X
모든 코드 블록(함수, if 문, for 문, while 문, try/catch 문 등) 내에서 선언된 변수는 코드 블록 내에서만 유효하며 코드 블록 외부에서는 참조할 수 없다. 즉, 코드 블록 내부에서 선언한 변수는 지역 변수이다.

  1. 함수 레벨 스코프 지원 O
    함수 내에서 선언된 변수는 함수 내에서만 유효하며 함수 외부에서는 참조할 수 없다. 즉, 함수 내부에서 선언한 변수는 지역 변수이며 함수 외부에서 선언한 변수는 모두 전역 변수이다.

이로인한 의도지 않은 전역변수가 선언되어 심각한 부작용이 발생되기도 하는데 이를 호이스팅이라고 한다.
그래서 ES6에서 let,const 를 도입했다.

var을 사용해서 변수를 선언할 때 값을 할당하지 않고
var score; 이름만 선언했을때 (2GB 프라이빗) 메모리 안에는 메모리공간이 확보가 되며 값은 undefined가 초기값으로 할당된다.


아래처럼 자바스크립트 엔진은 2단계에 거쳐 수행된다.

  1. 선언 단계: 변수 이름을 등록해서 자바스크립트 엔진에 변수의 존재를 알린다.
  2. 초기화 단계: 값을 저장하기 위한 메모리 공간을 확보하고 암묵적으로 undefined를 할당해 초기화한다.

변수는 선언과 할당을 동시에 해도 자바스크립트 엔진은 변수 선언할당을 2개의 문으로 나누어 실행한다.
변수들은 런타임 이전에 호이스팅 되지만 변수의 값은 런타임 때 실행된다.
고로 변수 선언(런타임 이전)-> undefined , 변수 값 할당(런타임)-> 80 이런식으로 된다고 한다.
undefined값이 저장되어 있던 메모리 공간을 지우고 할당된 값인 80이 저장되는게 아니라
새로운 메모리 공간을 확보하고 그곳에 저장한다고 합니다. 이때 undefined존은 TDZ!기억하자

이렇게 변수를 선언하고 할당하고 또 재할당 할때 항상 메모리에 저장되어있던 값을 지우고 새로운 값을 받아오는게 아니라 새로운 메모리 공간을 확보하고 그 자리에 값을 저장한다.
그러면 초기값,이전 80값은 그대로 남아있게 되는데
이럴때 가비지콜렉터가 메모리 공간을 주기적으로 검사하며 (주기는 알 수 없음) 더이상 사용하지 않는 메모리공간 즉,어떤 식별자(var.let,const)도 참조하지 않는 메모리를 해제하여 메모리 누수를 방지한다!


호이스팅

호이스팅(hoisting)은 JavaScript에서 변수 선언과 함수 선언이 스코프(scope)의 맨 위로 옮겨지는 현상을 의미합니다. 즉, 코드에서 변수나 함수를 선언하기 전에도 해당 변수나 함수를 사용할 수 있는 것처럼 보이는 것입니다.

변수 호이스팅의 경우, 변수를 선언하고 값을 할당하기 전에 해당 변수를 사용하면, 변수의 값은 undefined가 됩니다. 이는 변수의 선언이 스코프 맨 위로 옮겨지지만, 변수에 할당된 값은 옮겨지지 않기 때문입니다.

함수 호이스팅의 경우, 함수 선언을 스코프 맨 위로 옮기기 때문에, 함수를 선언하기 전에 호출할 수 있습니다. 이는 함수 표현식(function expression)의 경우에는 적용되지 않습니다. 함수 표현식은 변수 호이스팅과 마찬가지로 변수가 선언되기 전에 사용하면 에러가 발생합니다.

이때 선언과 초기화 사이를 TDZ(Temporal dead zone)이라 한다. 만약 해당 코드가 나오기 이전에 사용을 하려고 시도하면 TDZ에서 ReferenceError를 출력한다. 아래 예제에서는 let과 const의 변수 초기화가 이루어지기 이전에 사용을 하려 해서 TDZ에서 ReferenceError을 출력한 것이다.

호이스팅은 코드를 이해하고 디버깅하는 것을 어렵게 할 수 있기 때문에, 변수와 함수를 선언하는 위치에 유의하여 작성하는 것이 좋습니다.


회고

이날은 첫째날이라서 그런지 정신없었고 주제가 훅훅 바뀌었다...
이러면 안되는데 대화의 흐름도 생각해서 정보를 주고받아야 할 것 같다!
아마 1~2달정도는 아는 내용을 되짚는거라 수월할것 같다.

0개의 댓글