-
묵혔다가 꺼낸 JS - 렉시컬 스코프JS 2021. 10. 8. 01:38
렉시컬 스코프란?
렉시컬 스코프는 개발자가 함수와 변수를 선언한 후 컴파일 시 컴파일러가 토크나이징(렉싱) 할 때 선언한 함수의 스코프의 영역이 어디부터 어디까지인지, 변수가 어느 스코프에 들어있는지를 정해진 방식으로 만들어진 스코프의 영역이라고 말할 수 있겠다.
*렉시컬 스코프 방식은 자바스크립트 뿐만이 아닌 C, JAVA에서도 사용하는 방식이다.
그럼 설명을 코드로 한번 보면서 렉시컬 스코프가 어떤 방식을 가지고 있는지에 대해서 알아보겠다.
fn1을 실행 할 때 우리가 예상되는 결과는 40이 나올 것이다.
너무 당연하게 예상이 되지만 우리가 스코프와 자바스크립트 엔진이 되었다는 시선으로 바라보며 생각해보자.
자바스크립트 엔진은 실행되는 제일 안쪽 fn1의 return 하는 a, b가 참조하는 곳이 어디인지부터 유추한다.
그 과정의 첫번째로 자바스크립트 엔진은 fn1스코프 안에서 변수 a가 선언되었는지 확인하였지만 fn1 스코프에서 변수 a가 선언된 적이 없으므로 해당 스코프의 상위 스코프로 가게 된다.
상위 스코프로 갔더니 a라는 변수에 10이라는 값이 존재한다. 엔진은 이제 이 값을 들고 와서 사용한다.
다음으로 b변수를 fn1 스코프에서 찾는다.
b변수는 fn1스코프 내부에 존재하므로 엔진은 더 이상 상위 스코프를 탐색하지 않고, 이 값을 가지고 사용한다.
그리하여 연산된 값이 40이 되어 return 시켜주고, console.log를 호출해 콘솔 창에 40이라는 값을 보여준다.
이번에는 다른 코드로 한번 보자.
이번에도 아까 위와 같이 설명을 한번 해보겠다 ( 스피드웨건이 필요해! )
함수 실행을 가장 안쪽인 fn2함수부터 엔진은 실행한다.
fn2함수에서 현재 참조하고 있는 변수는 a, b, c이다.
a를 먼저 찾아보려고 fn2함수에 찾아보았으나 선언된 적이 없어 상위 스코프인 fn1으로 가서 찾는다. 하지만 fn1함수에도 없어 마지막 상위 스코프인 전역 스코프에서 찾게 되었고, a라는 변수가 있어서 그 값을 참조한다.
그리고 b라는 변수를 찾으려 fn2스코프에서 못 찾아 상위 스코프로 가서 b라는 변수를 찾는다.
엔진은 b라는 변수가 있는 것을 확인해 탐색을 멈추고, 그 값을 참조한다.
근데 c라는 변수는 어디서 참조한 것일까?
fn1에서 참조한 것이라 생각할 수 있겠지만 사실은 fn2의 매계변수에 할당된 c의 값을 들고 온 것이다.
여기서 알 수 있는 함수 스코프의 범위는 함수의 매계변수 ~ 함수 괄호 끝까지라는 것을 알 수 있는 중요한 대목이다.
더 정확하게 디버깅으로 확인해보자!
마지막 예는 나도 보면서 뭔가 싶었는데, 렉시컬 스코프적으로 생각하면 이해가 가는 코드다.
천천히 생각해보고 아래에 그 답이 있다.
같이 한번 보자.
fn1과 fn2를 실행하면 결과가 어떤 값이 나올까?
fn1을 실행하면 fn2의 b변수가 fn1의 b값을 참조할 것이라고 생각하였으나.... 아니었다.
(정답은 바로바로 👇)답을 보고 곰곰이 다시 생각해보면 당연히 틀린 거 같다.
왜냐하면 렉시컬 스코프는 토크나이징(렉싱) 때 스코프 영역을 함수가 선언된 영역에 대해 할당하기 때문에 지금 다시 보면 fn2가 fn1의 스코프 내부에 선언되어있지 않고, 전역 스코프에 선언되었으므로 a와 b의 값을 가져올 때는 전역 스코프의 값을 참조하게 되는 것이다.
오늘의 렉시컬 스코프와 정리.
(스코프를 들춰내면 들춰낼수록 지난 포스팅의 스코프 설명이 부족하다는 느낌이 든다. 부족한 스코프에 대한 비밀은 다음 포스팅에도 계속 적게 될 것 같다.)- 렉시컬 스코프는 함수와 변수가 정의된 후 컴파일러가 토크나이징(렉싱)을 할 때 각 함수와 변수가 어떤 스코프의 영역에 할당되는지에 대해 정해지는 방식임을 알았다.
- 변수를 참조 시 해당 변수가 없다면 상위 스코프에서 변수를 참조하게 된다.
여기서 말하는 상위 스코프는 함수를 호출한 스코프가 아닌 1번째 정리에서 적은 것과 같이 함수가 정의된 스코프의 상위 스코프를 말하는 것이다.
후기.
마지막 문제를 보고 틀렸을 땐 정말 머리를 한대 세게 맞은 것 같다...
언어의 동작 순서와 언어의 깊이가 중요하다는 것을 다시 한번 느끼며, 오늘도 모르는 지식을 하나 더 배워서 한편으로는 부족한 지식 통장에 지식이 쌓이니 기분이 좋다.
(정말, 정말, 정말) x 100 도움받은 블로그
Su Bak님의 블로그
(JavaScript) Lexical Scope(Static Scope) and Dynamic Scope(JavaScript) Lexical Scope(Static Scope) and Dynamic Scope
프로그래밍에서 Scope란 변수의 유효범위를 나타내는 용어인데요(Scope에 대한 자세한 사항은 이전의 글을 참고해주시기 바랍니다).
medium.com
sjk5766님의 블로그
Lexical Scope, Closure 정리Lexical Scope, Closure 정리
공부한 내용을 블로그에 쓰는 이유는 머리로 정리하는 것 보다 글로 정리하는 것이 더 좋다는 믿음 때문입니다. 그래서 인터넷에 Closure에 대한 양질의 글이 많음에도 꾸역꾸역 포스팅을 합니다.
medium.com
그리고 믿음직스러운 MDN
스코프 - 용어 사전 | MDN스코프 - 용어 사전 | MDN
현재 실행되는 컨텍스트를 말한다. 여기서 컨텍스트는 값과 표현식이 "표현"되거나 참조 될 수 있음을 의미한다. 만약 변수 또는 다른 표현식이 "해당 스코프"내에 있지 않다면 사용할 수 없
developer.mozilla.org
'JS' 카테고리의 다른 글
묵혔다 꺼낸 JS - 클로저 (0) 2021.10.15 묵혔다가 꺼낸 JS - 스코프의 효용성, 블록 스코프, 호이스팅 (0) 2021.10.12 묵혔다 꺼낸 JS - 컴파일러와 스코프 (0) 2021.10.04 묵혔다 꺼낸 JS - 암시적 변환 (==연산자의 비교연산) (0) 2021.09.29 묵혔다 꺼낸 JS - 암시적 변환 (+, -, &&, ||) (0) 2021.09.28