4.3. 변수선언
👾 var의 단점
블록 레벨 스코프를 지원하지 않으며, 함수 레벨 스코프를 지원한다.
이로 인해 의도치 않게 전역 변수가 선언되어 부작용이 발생하기도 한다.
👾 undefined
var score; //변수 선언
cosole.log(score); //undefined
score = 100; //변수 초기화
- 변수값을 할당하기 전 메모리 공간은 js엔진에 의해 undefined라는 값이 할당되어 초기화된다.
- 선언 단계: 변수 이름을 등록해서 js 엔진에 변수의 존재를 알린다.
- 초기화 단계: 값을 저장하기 위한 메모리 공간을 확보하고 암묵적으로 undefined를 할당해 초기화 한다.
- var 키워드의 경우 선언과 동시에 초기화가 이루어진다. var 키워드로 선언한 변수는 어떠한 값도 할당하지 않아도 undefined라는 값을 갖는다.
- 변수를 초기화하지 않는 경우, 기존의 확보된 메모리 공간에는 이전에 다른 애플리케이션이 이용했던 데이터(=쓰레기 데이터)가 남아있다. 메모리 공간을 확보하고 값을 할당하지 않은 상태에서 곧바로 변수 값을 참조하면 쓰레기 값이 나올 수 있다. 자바스크립트의 경우 undefinde로 암묵적인 초기화를 진행함으로써 쓰레기값을 참조하는 위험으로부터 안전하다.
- 모든 식별자는 *실행 컨텍스트에 등록된다.
실행 컨텍스트
- 소스코드의 평가&실행을 위해 필요한 환경을 제공하고 코드의 실행결과를 실제로 관리하는 영역.
- 식별자와 스코프 관리도 실행 컨텍스트에서 진행된다.
4.4 변수 선언의 실행시점과 변수 호이스팅
👾 변수 호이스팅
console.log(score); //undefined
var score;
js는 인터프리터에 의해 한줄씩 순차적으로 실행되는 인터프리터 언어다. 따라서 순차적으로 변수 선언 이전에 console.log(score);가 실행된다.
선언되지 않은 변수를 사용하는 경우 참조 에러가 발생하므로 위의 코드도 에러가 발생해야 한다. 하지만 위 코드의 출력 결과는 참조에러가 아닌 undefined이다. (console.log 실행 시점에 이미 변수 선언과 초기화가 완료되었다는 뜻)
이유👉 변수 선언은 *런타임 이전 단계에서 먼저 실행되기 때문이다.
(*런타임: 소스코드가 한줄씩 실행되는 시점)
자바스크립트 엔진은 소스코드를 순차적으로 실행하기 전 먼저 소스코드 평가과정을 거친다. 모든 선언문(var, let, const, function, function*, class 키워드를 사용한 모든 선언문)을 소스코드에서 찾아내 먼저 실행하는 것이다. 위의 코드와 같은 경우 `console.log(score);` 코드 실행 이전에 js 엔진이 이미 score의 선언을 확인했으므로, `console.log(score);`의 결과로 undefined가 출력된다.
이처럼 변수 선언문이 코드의 선두로 끌어올려진 것처럼 동작하는 js 특유의 특징을 변수 호이스팅이라 한다.
4.5 값의 할당
var score; //변수 선언
score = 100; //값 할당
// 동시 진행
var score = 100;
위의 마지막 줄 코드는 변수 선언과 초기화를 동시에 진행하는 코드.
but, js 엔진은 변수 선언과 값의 할당을 2개의 코드로 나누어 각각 실행한다.
❗ 변수 선언과 할당의 실행 시점이 다름에 주의
변수 선언은 소스코드가 순차적으로 실행되는 시점인 런타임 이전에 먼저 실행되지만 값의 할당은 런타임에 실행된다. 아래 예제 참고.
console.log(score); //undefined
var score; //변수 선언
score = 100; //값의 할당
console.log(score); //80
변수에 값을 할당할 시, 변수를 선언할 때의 초기화 값 undefined가 저장되어 있던 메모리 공간을 지우고 그 공간에 100을 할당하는 것이 아니다. 새로운 메모리를 확보하고 그곳에 100을 할당시킨다. 아무도 참조하지 않는 undefined는 시간이 지난 후 가비지 컬렉터에 의해 자동으로 해제된다.
console.log(score); //undefined
score = 100; //값의 할당
var score; //변수 선언
console.log(score); //??
위 예제의 마지막 콘솔 출력 결과는 100이다.
그 이유는 아래와 같다.
var score; //변수 호이스팅에 의해 끌어올려진 변수 선언
console.log(score); //undefined
score = 100; //값의 할당
console.log(score); //100
4.6 값의 재할당
👾 재할당: 이미 값이 할당되어 있는 변수에 새로운 값을 또 다시 할당하는 일. 즉 현재 변수에 저장된 값을 버리고 새로운 값을 저장하는 것
var score = 90;
score = 100;
값의 할당과 마찬가지로, 변수의 이전 값이 저장되어 있던 메모리 공간을 지우고 그 공간에 새로운 값을 할당하는 것이 아니다. 새로운 메모리를 확보하고 그곳에 새로운 값 100을 할당시킨다.
불필요한 값은 가비지 컬렉터에 의해 메모리에서 자동 해제되며, 그 시기는 예측할 수 없다.
* 가비지 컬렉터
애플리케이션이 할당한 메모리 공간을 주기적으로 검사하여 더 이상 사용되지 않는 메모리(어떤 식별자도 참조하지 않는 메모리 공간)를 해제하는 기능. 가비지 콜렉터를 이용해 메모리 누수를 방지할 수 있다.
*언매니지드 언어
개발자가 명시적으로 메모리를 할당하고 해제할 수 있도록 저수준 메모리 제어 기능을 제공하는 언어. 개발자의 역량에 따라 최적의 성능 보장. but, 반대의 경우 치명적 오류 생산 가능성 존재
ex) C언어 - malloc(), free()
*매니지드 언어
메모리 할당 및 해제를 위한 메모리 관리 기능을 언어 차원에서 담당하고 개발자의 직접적인 메모리 제어를 허용하지 않는 언어. 더 이상 사용하지 않는 메모리 해제는 개발자가 아닌 가비지 콜렉터에서 수행한다. 개발자의 역량에 의존하지 않으므로 어느 정도 일정한 생산성을 확보할 수 있으나 성능 면에서 어느 정도의 손실은 존재.
ex) 자바스크립트
4.7. 식별자 네이밍 규칙
👾 네이밍 컨벤션
- 변수, 함수 이름: 카멜 케이스 (let firstName;)
- 생성자 함수, 클래스 이름: 파스칼 케이스 (class FirstName{ })
출처: 모던 자바스크립트 Deep Dive (이웅모 저, 위키북스)
'웹 프로그래밍 > JavaScript | TypeScript' 카테고리의 다른 글
[땅콩코딩] 타입스크립트 강좌 내용정리(함수의 타이핑, 선택적 매개 변수와 기본 매개변수 / 클래스와 오브젝트 ) (0) | 2024.03.14 |
---|---|
[땅콩코딩] 타입스크립트 강좌 내용정리(열거형과 리터럴 타입) (0) | 2024.03.14 |
[땅콩코딩] 타입스크립트 강좌 내용정리(TS의 특성, 설치 및 환경설정, 타입추론, 타입명시, 인터페이스) (0) | 2024.03.11 |
[오류해결] Uncaught TypeError TypeError: Cannot set properties of null (setting 'onclick') (0) | 2023.03.22 |
[자바스크립트 문법] Array.prototype.map(), Array.prototype.reduce(), Array.prototype.filter() (0) | 2023.02.19 |
[ZeroCho] ES2021 자바스크립트 강좌 10장 클래스_텍스트 RPG 게임 만들기 (0) | 2022.08.08 |