http://119.201.123.184/30stair/x_length/x_length.php?pname=x_length
오늘은 dovelet 문제를 이용해 요즘 관심있게 보고 있는 동영상(https://youtu.be/QyUFheng6J0에서 보여준 예제를 간단하게 따라해 봤습니다.
var b; //global 변수
var execute = (function(){
a = 4; //이 변수는 클로저로 접근 할 수 업습니다.
b = 3; //이 변수는 클로저로 접근 가능합니다.
function result(){ //이 함수는 클로저로 접근가능합니다.
var sum = a + b; //a, b 클로저를 사용하고있습니다.
return sum * (Math.PI + Math.sqrt(2)); //결과값. 딱히 제가 하려던 얘기와는 상관 없습니다.
}
return result; // result 레퍼런스를 반환합니다. 이순간부터 result 와 그 주변 환경은
//더이상 할일이 없어질 때까지, 즉 더이상 접근 방법이 없을 때까지
//메모리가 남이 있습니다
var a; // 익명함수의 메모리에 a가 이미 등록이 되어있기 때문에 위의 a는 클로저로는 접근 할 수 없습니다.
})();
console.log(execute().toFixed(3)); //실행이 되고서 더이상 result에 대한 접근 수단이 없기 때문에 남아 있던 메모리가
//반환됩니다.
한번 이 코드를 실행을 제가 아는데로 따라가 보겠습니다.
먼저 첫번째 실행환경 구축 단계에 global 에 b, execute가 등록이 됩니다.
현재 레벨에서는 d, 와 execute 변수 모두 undefined로 정의되어 있습니다.
global 환경
- b = undefined
- execute = undefined
이제 환경 구축단계에서 실행으로 넘어와에서 execute의 대입 연산자가 수행이되며 가로안의 함수객체의 환경 구축이
시작됩니다.
첫번째에 a와 b가 있지만 환경 구축 단계에서는 건너 뜁니다.
result를 환경에 추가하고, 맨 밑에 보면 var a가 있는데 이 역시 환경에 등록시킵니다.
global 환경
- b = undefined
execute = undefined -> 아직 실행이 되지 않아 execute에는 값이 저장되지 않았습니다.
익명 함수 환경
- result(function)
- a = undefined
이제 실행 단계에서 a는 4가 저장이되고 b에는 3이 저장이 되는데 전혀 다른 메모리에 저장이된다는 것을 알 수 있습니다.
a는 이미 익명함수 환경에 등록이 되어 있기 때문에 클로저로 접근할 수 없습니다. a 는 오직 익명 함수 내에서만
접근 가능한 변수입니다.
반면 b는 3이 저장이 되는데 이는 클로저로 접근 가능합니다. 왜냐하면 b는 익명 함수 환경내에 없기 때문에
스코프 체인을따라 글로벌 환경의 b에 3을 저장합니다.
그런뒤에 등록된 result의 를 반환하게 됩니다.
global 환경
- b = 3
- execute = result(function reference)
익명함수 환경
- a = 4
- result(function)
제가 동영상을 보면서 인상깊었던 점은 이때부터 이루어지는 메모리의 생성과 소멸이였습니다.
익명함수 내의 result함수는 실행단계에서도 메모리가 할당되어지지 않습니다.
단, result를 아직은 접근 할 수있는 수단, 즉 execute를 통해 접근이 가능하기 때문에
result의 외부환경, 즉 익명함수의 환경의 메모리는 사라지지 않고 유지되어집니다.
result함수 객체의 메모리가 할당되는 시점은 execute에 저장되어있는 result 레퍼런스를 불러왔을 때
비로소 result에 메모리가 할당이 됩니다. 그렇지만 execute() 뒤에는 더이상 result 레퍼런스에 접근할 방법이
전혀 없습니다. 이 때, 즉 더이상 메모리에 접근할 방법이 없을 때 비로소 메모리의 반환이 이루어집니다.
스택에 쌓여 있는 데로 result의 메모리가 반환되고 그 다음 익명함수의 메모리가 반환이 이루어집니다.
현재 메모리는 이렇습니다.
global 환경
- b = 3
- execute = result(function)
제가 위에서 굵게 썼듯이 메모리의 생성과 소멸은 그 근본을 레퍼런스에 대한 접근 여부에 달렸다는 중요한 교훈을 얻을 수
있었던 시간이었던 것 같습니다. 또한 익명 함수 안의 return 뒤에 var a를 선언 한것은 뒤통수를 한대 얻어 맞은 느낌이었고
변수 호이스팅이 왜 어떻게 이루어지는지에 대한 이해를 높이는 계기가 되었던 것 같습니다.
다음에는 이벤트 루프의 실행 과정에 대해 리뷰를 해봐야 겠습니다.