해당 내용은 '코어 자바스크립트' 서적을 참고하여 작성되었으며, 초보 개발자에게 유익한 책을 지필해주신 지은이 정재남 님께 감사의 말씀을 드립니다.
function hoist(x) {
console.log(x); // 1
var x;
console.log(x); // 1
var x = 2;
console.log(x); // 2
}
hoist(1);// 실행컨택스트 구성 시작!
// 위 코드에 호이스팅 현상을 적용하여 표현하자면 아래와 같이 다시 나타낼 수 있다.
function hoist() {
// 식별자 정보(environmentRecord)만을 끌어올린다
var x;
var x;
var x;
// 그 다음 할당이 이루어진다
x = 1;
console.log(x);
console.log(x);
x = 2;
console.log(x);
}
hoist();
// 함수 선언문
function func(){}
// 함수 표현식
var func = function(){}
declare(); // a
function declare() {
console.log('a');
}
express(); // error: express is not a function
var express = function () {
console.log('a');
};
/* 왜 그럴까?
위 코드에 호이스팅 현상을 적용하여 다시 표현하자면 다음과 같다*/
// 함수 선언문은 호이스팅 적용시 함수 전체를 끌어올린다
function declare() {
console.log('a');
}
// 함수 표현식은 호이스팅 적용시 식별자만 끌어올린다
var express;
declare();
express(); // 그래서 express 할당된 함수가 없기 때문에 에러가 발생한다
express = function () {
console.log('a');
};
함수 선언문 vs 함수 표현식 : 무엇이 더 권장되는가
결론적으로, 함수 표현식을 권장하고 있다. 왜냐하면 개발자가 코드를 볼때 위에서 아래로 읽어가며, 함수를 만든 뒤에 그 함수를 실행되어야 혼란이 없기 때문이다. 호이스팅 현상 같은 경우 맨 마지막에 선언된 변수를 기준으로 할당 및 실행이 이루어진다. 그래서 만약 같은 이름이지만 다른 내용의 함수 선언문이 두개 존재한다면 나중에 선언된 함수가 전역으로 적용되는 불상사가 일어날 수 있다. 하지만 함수 표현식으로 한다면 차례대로 다른 내용이 할당될 수 있기 때문에 원하는 순서대로 함수가 적용된다. 그리고 함수 선언 이전에 실행됐을 때에 에러가 발생하여 디버깅에도 용이하다.
스코프(scope)란?
식별자에 대한 유효범위
스코프체인이란?
'식별자의 유효범위'를 안에서부터 바깥으로 차례로 검색해나가는 것
outerEnvironmentReference
스코프체인을 가능하게 만드는 도구이자, LexicalEnvironment의 두번째 수집 자료
(첫번째는 environmentRecord)
// LexicalEnvironment = LE / outerEnvironmentReference = OE
var a = 1;
var outer = function(){ // 2. 이 시점에서의 LE 정보가 outer 함수의 OE 정보로 들어간다
var inner = function(){ // 4. 이 시점에서의 LE 정보가 inner 함수의 OE 정보로 들어간다
console.log(a);
var a = 3;
}
inner(); // 3. inner 실행컨택스트 구성 시작!
console.log(a);
}
outer(); // 1. outer 실행컨택스트 구성 시작!
console.log(a);
위 예시 추가 설명
2번 시점에서 받는 OE 정보는 전역컨택스트의 LE 정보이며, [Global, {a, outer}]
이다.
4번 시점에서 받는 OE 정보는 outer의 LE 정보이며, [outer, {inner}]
이다.
console.log(a)
에서 식별자 a
정보로 접근하려 할때 순서가 있다.전역변수와 지역변수
위에서 설명한 스코프와 변수 은닉화의 연장선으로 이해할 수 있는 개념이다.
전역 공간에서 선언한 변수를 전역변수, 특정 함수 내에서 선언한 변수를 지역변수 라고 한다.
코드에 혼란을 줄이기 위해서는 가급적 전역변수를 줄이는게 좋다고 한다.