스코프 내부 어디서든 변수 선언은 최상위에 선언된 것처럼 행동한다.
let은 var와 다르게 에러가 난다. 호이스팅이 이루어는 지지만 TMZ(Temporal Dead Zone)라는 것에 let, const는 영향을 받는다. 할당하기 전에 사용하지 못하게 하는것이다.
var는 호이스팅이 발생하면 선언과 초기화가 동시에 이루어져 실행 시점의 스코프 최상단에서 해당 변수에 대한 메모리가 살아잇어 선엄부 위치에 상관없이 할당이 가능하다.
let, const는 호이스팅이 발생하면, 선언만 이루어지고 실행 시점에서 실질적인 선언부를 만날 때까지 초기화는 이루어지지 않는다. 그래서 해당 변수의 메모라가 없으니 선언부 상단에서 참조 할당이 불가능하다.
var = 함수스코프
let, const = 블록스코프
초기화 : 식별자에 메모리를 할당하고 undefined 상태를 부여한다.
var name; //호이스팅
console.log(name); //undifined
name = 'star';
// name 이라는 변수만 상단으로 올려진것이고, 값은 그 자리에 있는것!
let age = 30;
function showAge(){
console.log(age); //에러
let age = 20;
}
showAge();
calcurator.html:30 Uncaught ReferenceError: Cannot access 'age' before initialization 라는 에러를 발생시킨다.
이미 let으로 선언한 age는 호이스팅 되었고 스코프 안쪽에서 (여기서 스코프는 showAge 함수 내부 {}) let으로 선언된 age가 호이스팅을 일으킴
const text = 'text'; // 전역 변수(클로벌 변수), 전역 스코프(글로벌 스코프) -> 1
{
const text = 'inside text'; // 지역 변수(로컬 스코프), 지역 스코프(로컬 스코프) -> 2
{
console.log(text); //'inside text' -> 3
}
}
// 위 예제에서는 inside text 가 출력된다.
렉시컬 : 함수가 선언된 시점에서의 유효범위를 갖는다. 이런 유효범위 방식은 정적유효범위(static scope) 혹은 렉시컬(lexical scope)라 부른다.
실행 컨텍스트 : 실행할 코드에 제공할 환경 정보들을 모아놓은 객체
각 블럭은 자신만의 렉시컬 환경 내부 오브젝트를 가지고 있으며 실행 컨텍스트(Execution Context)에 코드의 실행 순서가 아래처럼 쌓인다.
블럭3 스코프 렉시컬 환경
블럭2 스코프 렉시컬 환경
전역1 스코프 렉시컬 환경
렉시컬 환경은 스코프 체인을 통해 돌아다니며 찾는 것은 성능이 좋지 못하니 최대한 팔요한 곳에 변수를 정의하며 메모리 절약과 성능 향상을 위해 노력해야한다.
내부에서는 외부에 있는 변수에 접근 가능하나 외부에서는 내부에 있는 변수 접근이 가능한 이유도 위의 실행 컨텍스트로 설명 가능하다.
가비지 컬렉터 : 컴퓨터가 정보를 처리할 때도 공간(memory)이 필요하다. 그로 인해 생겨났으며, 필요로 쓸모 없어진 객체가 차지하는 메모리를 자동으로 해제하는 것
const global = 1; // 글로벌 변수는 앱이 종료될때까지 메모리에 계속 유지.
{
const local = 1; // 블럭 내부에서만 존재하고, 블럭이 끝나면 가비지 컬렉터에 의해 소멸.
}
function print() {
if(true) {
let temp = 1; // 함수 내부에서도 필요한 경우 블록 안에서 변수를 선언하고 사용하도록.(!중요)
}
}