record
)1. 매개변수 및 변수는 선언부를 호이스팅
// 적용 전
function a (x) {
console.log(x); // 예상 1
var x;
console.log(x); // 예상 undefined
var x = 2;
console.log(x); // 예상 2
}
a(1);
// 매개변수 적용
function a () {
var x = 1;
console.log(x);
var x;
console.log(x);
var x = 2;
console.log(x);
}
a(1);
// 호이스팅 적용
function a () {
var x;
var x;
var x;
x = 1;
console.log(x); // 1
console.log(x); // 1
x = 2;
console.log(x); // 2
}
a(1);
2. 함수 선언은 전체를 호이스팅
// 적용 전
function a () {
console.log(b); // 에러 or undefined
var b = 'bbb';
console.log(b); // 예상 'bbb'
function b() { }
console.log(b); // 예상 fn
}
a();
// 호이스팅 적용
function a () {
var b; // 변수 선언부 호이스팅
function b() { } // 함수 선언은 전체를 호이스팅
console.log(b); // fn
b = 'bbb'; // 변수의 할당부는 원래 자리에
console.log(b); // 'bbb'
console.log(b); // 'bbb'
}
a();
// 함수선언문 -> 함수 표헌식
function a () {
var b; // 변수 선언부 호이스팅
var b = function b() { } // 함수 선언은 전체를 호이스팅
console.log(b);
b = 'bbb'; // 변수의 할당부는 원래 자리에
console.log(b);
console.log(b);
}
a();
3. 함수 선언문, 함수 표현식
함수 정의의 3가지 방식
// 함수 선언문 // 함수명 a가 곧 변수명 // function 정의부만 존재, 할당 명령이 없는 경우 function a () { /* ... */ } a(); // 실행 ok // 함수 표현식 // 정의한 function을 별도 변수에 할당하는 경우 // (1) 익명함수표현식 : 변수명 b가 곧 변수명(일반적 case) var b = function () { /* ... */ } b(); // 실행 ok // (2) 기명 함수 표현식 // 변수명은 c, 함수명은 d // d()는 c() 안에서 재귀적으로 호출될 때만 사용 가능하므로 사용성에 대한 의문(잘 안씀) var c = function d () { /* ... */ } c(); // 실행 ok d(); // 에러!
함수 선언문을 주의해야하는 이유
💡 함수전체가 호이스팅 되기때문에 코드 전체에 영향을 미치게 됨
// 함수 선언문 // 100번째 줄 : 시니어 개발자 코드(활용하는 곳 -> 200군데) // hoisting에 의해 함수 전체가 위로 쭉! function sum (x, y) { return x + y; } // 5000번째 줄 : 신입이 개발자 코드(활용하는 곳 -> 10군데) // hoisting에 의해 함수 전체가 위로 쭉! function sum (x, y) { return x + ' + ' + y + ' = ' + (x + y); }
함수 표현식이었다면?
// 함수 표현식 // 함수 선언부만 위로 쭉! // 이 이후부터의 코드만 영향을 받아요! var sum = function (x, y) { return x + y; } // 함수 선언부만 위로 쭉! // 이 이후부터의 코드만 영향을 받아요! var sum = function (x, y) { return x + ' + ' + y + ' = ' + (x + y); }
식별자에 대한 유효범위
대부분의 언어에 존재
식별자의 유효범위를 안에서부터 바깥으로 차례로 검색해나가는 것
스코프 체인이 가능토록 하는 것(외부 환경의 참조정보)
전역 컨텍스트의 LexicalEnvironment
를 참조💡 각각의 실행 컨텍스트는 LE 안에 record와 outer를 가지고 있고, outer 안에는 그 실행 컨텍스트가 선언될 당시의 LE정보가 다 들어있으니 scope chain에 의해 상위 컨텍스트의 record를 읽어올 수 있다.