8월 16일 강의 노트 정리(1)입니다.
실행 컨텍스트는 우리가 실행할 코드에 변수 정보들을 담아 놓은 환경입니다.
접근할 순 없지만 항상 생성되고 함수가 실행될 때마다 실행 컨텍스트가 실행됩니다. 즉, 하나의 함수는 본인의 고유한 실행 컨텍스트를 가지고 있습니다.
변수 정보
어떤 변수가 있고 어떤 변수를 끌어올릴 것이고(hoisting
) 변수의scope
,scope chain
은 무엇이고 this는 어디를 바라보고(binding
) 있는지
자바스크립트를 실행해 파일이 열리는 시점에 실행할 코드들을 콜 스택에 쌓아 올렸다가, 가장 위의 컨텍스트와 관련된 코드를 실행하는 식으로 구성되어 있습니다. 즉, 이런 환경과 순서가 항상 보장되어 있습니다.
전역 영역에 존재하는 전역 컨텍스트입니다.
실행 컨텍스트 콜 스택에 가장 먼저 들어오는 단 하나의 코드입니다.
함수가 실행될 때마다 생성되는 컨텍스트입니다.
자바스크립트 내장 함수로 특정 코드를 실행될 때 생성되는 컨텍스트입니다.
Lexical
의 정보를 그대로 감싸놓은 스냅샷 ( 종류 )
함수가 가지고 있는 변수, 매개변수, 인자, 정의와 같은 정보들을 담아 놓는 부분입니다.
record
: 변수에 대한 정보, 어떻게 hoisting
되고 어떤 식으로 사용되는지 ?
Outer
: scope chain
들에 대한 내용
hoisting
은 변수의 선언을 끌어올리는 것을 말합니다.
hoisting
으로 인해 변수가 선언되기 전에 호출했을 때 오류가 나지 않게 됩니다.
console.log(name); // 에러가 아닌 undefined 출력.
var name = "dongwon";
다음과 같이 생각하면 쉽습니다.
var name; // name 선언. 현재 undefined
console.log(name); // undefined
name = "dongwon";
함수의 hoisting
은 다음과 같이 2가지로 구분할 수 있습니다.
함수를 정의한 것입니다.
function getName(name) {}
함수 선언문의 hoisting
함수 선언문으로 작성했을 때 hoisting
이 되고 호출도 가능합니다.
다음 코드에서 함수가 선언되기 전에 호출되지만 hoisting
이 되어 기대한 대로 결과값이 나옵니다.
getName("dongwon");
function getName(name) {
cosnole.log(name); // dongwon 출력
}
값으로 표현할 수 있는 것, 자바스크립트 해석기가 계산하여 값을 구할 수 있는 구절입니다.
var a = function () {};
a();
함수 표현식의 hoisting
함수 표현식은 할당된 함수가 hoisting
시점에 올라오지 않아 hoisting
이 되지 않습니다.
console.log(a); // 값은 undefined
a(); // 타입 에러 발생
var a = function () {
console.log("a");
};
var
, let
, const
셋 다 hoisting
은 되지만 var 과의 차이점은 할당이 되기 전까지 TDZ에 존재합니다.
TDZ는 간단하게 말해서 hoisting
돼서 변수들을 알긴 알지만 못쓰게 막아놓은 공간이라고 생각하면 됩니다. 즉, Lexical
환경에서 정보는 가지고 있으면서도 변수를 못 쓰게 막는 공간을 TDZ
라고 합니다.
scope
는 변수가 살아있는 범위를 말합니다. 바꿔 말하면 살아있지 않는 변수도 존재합니다. 이러한 특징 때문에 스코프만 잘 구분한다면 동일한 변수명을 여러 번 쓸 수 있습니다.
코드 어디에서든 참조가 가능한 scope입니다.
var
키워드로 만든 변수가 이 전역 객체에 속합니다.
브라우저에서는 window
, node.js에서는 global
로 접근할 수 있습니다.
var a = "dongwon";
console.log(a); // dongwon
console.log(window.a); // dongwon
함수 내에서만 참조가 가능한 scope
입니다. if, for
문과 같은 {} 블럭과는 상관없이 오로지 함수 내의 scope
입니다.
function a() {
var a = "dongwon";
}
console.log(a); // a is not defined
주의 할 점
let, const의scope
는 {} 블럭 단위입니다. ( var과의 차이점 ){ let x = 1; } console.log(x); // x is not defined
변수가 해당 scope
에 있지 않을 때, 안에서 바깥으로만 차례로 해당 변수를 탐색하는 것입니다.
function sum() {
var a = 3;
var b = 5;
function inner() {
var b = 7;
// a는 sum의 a, b는 inner의 b
a = a + b;
console.log(a); // 10
}
// inner 호출 전의 a. 즉 3
cosnole.log(a);
inner();
// inner 의 실행 결과로 바뀐 a
cosnole.log(a); // 10
}
- inner 함수 안에 a = a + b 에서
inner scope
에 a가 없으므로 바깥sum scope
의 a를 의미합니다.- 마찬가지로 b는
inner scope
에 존재하므로sum scope
의 b가 아닌inner scope
의 b를 의미합니다.- inner 함수 안에서 바깥 scope의 변수를 조작했다면 바깥 scope의 변수도 값이 조작됩니다.