스코프, 호이스팅, TDZ
변수를 선언하고 값을 할당하는 것으로 프로그램의 상태를 관리할 수 있다.
이 변수는 전역 또는 코드블럭, 함수 내에 선언하는데 이때 코드 블록이나 함수는 중첩될 수 있다.
식별자는 자신이 어디에서 선언되었는지를 구별해 자신이 유효한 범위를 갖는다.
쉽게 표현하면 변수가 겹칠 수 있으니까 변수가 선언될 때 <나는 여기 범위에서만 호출할 수 있어!> 라고 구분해 주는 것이다.
var x = 'global';
function foo () {
var x = 'function scope';
console.log(x);
}
foo(); // ?
console.log(x); // ?
위 예제처럼 전역에 선언된 변수 x('global')는 어디에서든 참조가 가능하다. 하지만 함수 foo 내에서 선언된 변수 x('function scope')는 함수 foo 내부에서만 참조할 수 있고 외부에서는 참조할 수 없다.
이러한 규칙을 <스코프>라고 한다.
예를 들어서
function catName(name) {
console.log("제 고양이의 이름은 " + name + "입니다");
}
catName("호랑이");
/*
결과: "제 고양이의 이름은 호랑이입니다"
*/
위의 코드가 일반적으로 쓰이는 방법인 선언을 하고 호출을 하는 식이라면
catName("클로이");
function catName(name) {
console.log("제 고양이의 이름은 " + name + "입니다");
}
/*
결과: "제 고양이의 이름은 클로이입니다"
*/
위의 코드처럼 호출을 한 다음에 선언을 할 수 있는 것이 호이스팅 덕분이다.
단, var로 선언한 변수의 경우 undefined로 변수를 초기화 한다. 반면에 let 과 const로 선언한 변수는 호이스팅 시 변수를 초기화 하지 않는다.
함수 선언문과 함수 표현식에서 호이스팅 방식의 차이
우선 함수 선언문과 함수 표현식부터 알아보자.
함수 선언식 (function declartion)
함수명이 정의되어 있고, 별도의 할당 명령이 없는 것
function sum(a,b) {
return a + b;
}
함수 표현식 (function Expression)
정의한 function을 별도의 변수에 할당하는 것
const sum = function(a,b) {
return a + b;
}
주요 차이점은
함수 선언문: 함수 전체를 호이스팅 한다.
함수 표현식: 선언부와 할당부를 나누어 선언부만 호이스팅 한다.
실행 컨텍스트와 콜 스택
실행 가능한 코드
(1) 전역코드: 전역 영역에 존재하는 코드
(2) Eval 코드: eval 함수로 진행되는 코드
(3) 함수코드:함수 내에 존재하는 코드
코드를 실행하기 위한 여러가지 정보
(1) 변수
(2) 함수 선언
(3) 변수의 scope (유효 범위)
(4) this
즉, 실행 컨텍스트(Execution context)는 우리가 작성한 코드가 실행되는 환경을 말하며, scope, hoisting, this, function, closure 등의 동작원리를 담고 있는 자바스크립트의 핵심원리를 말한다.
스코프 체인
변수 은닉화
function a(){
let temp = 'a'
return temp;
}
// console.log(temp) error: temp is not defined
const result = a()
console.log(result); //a
위 함수 내부적으로 선언된 temp에는 직접적으로 접근을 할 수 없다.
함수 a를 실행시켜 그 값을 result라는 변수에 담아 클로저를 생성, temp의 값에 접근이 가능하다.