fn2 함수를 fn1 함수에서 호출하였을 때 fn2 에서 참조하려는 변수 l1은 함수 fn1 내에 존재하고 있다.
= "그럼 당연히 fn1에서 fn2를 호출했으니 부모 함수인 fn1에 존재하는 변수 l1을 당연히 fn2에서 참조할 수 있지 않을까?" 라고 생각을 하였다.
그러나 변수 l1을 찾을 수 없다 라는 Reference Error 가 발생하였다. 왜일까?
Call Stack 부분의 fn2 함수를 클릭하여 Scope-Chain을 보자.
fn2 함수 내의 지역스코프, Script 내의 지역스코프를 보게 되면 변수 l1은 존재하지 않는다.
이번엔 fn1 함수의 Scope-Chain을 보자. fn1 내의 지역스코프에는 변수l1이 존재하고 전역스코프에는 변수 l0 만이 존재한다.
이로써 알 수 있는 것은 fn1의 로컬이 fn2의 Scope-Chain에 존재하지 않고 fn2에는 fn2만의 독립적인 로컬이 존재한다. 그 다음에는 전역적인 스코프의 내용만이 들어온다.
따라서 결론은 fn1 함수 내에서 fn2 함수를 호출했다고 하더라도 fn1 함수내에서 정의된 변수를 참조할 수 없다. 만약에 어디에서 호출했느냐에 따라 접근할 수 있는 유효범위가 달라진다면 우리는 그것을 Dynamic scope (동적스코프) 라고 부른다. 그러나 자바스크립트는 Static scope 또는 Lexical scope(정적스코프) 를 채택하고 있다.
이번엔 fn2 함수를 fn1 함수에 넣고 똑같이 실행시켜보았다.
이번엔 참조에러 없이 정상적으로 동작된 것을 볼 수 있다.
다음엔 브레이크포인트를 걸고 Scope 탭을 보았다.
아까는 존재하지 않았던 Closure라는 탭이 로컬스코프와 전역스코프 사이에 생긴 것을 볼 수 있다. Closure 탭 안에는 fn1 함수의 변수 l1 이 기록되어 있다.
이렇게 흘러갔다고 말할 수 있다.
fn2 함수 스코프 내에서 변수 l1을 탐색
없어서 다음 부모 스코프인 fn1을 탐색
fn1에 변수 l1이 존재
fn2에서 fn1 함수 내에 있는 변수 l1 참조.
이로써 최종적으로 알 수 있었던 것은 자바스크립트는
어떤 함수가 있을 때 그 함수의 유효범위는 그 함수가 어디서 호출되었느냐가 아니라 어디서 정의되었느냐에 따라 결정된다는 것이다.
함수는 한번만 정의를 할 수 있다. 정적이다고 말할 수 있으며
정적스코프 또는 렉시컬스코프(lexical scope)라고 부른다. 자바스크립트는 정적스코프(static scope)를 채택하고 있다!
위의 코드는 더하기1 이라는 변수에 숫자 1을 매개변수로 넘겨준 더하기함수공장 이라고 하는 함수가 저장되어있다. 이로써 더하기함수공장 이라는 함수는 1이라는 숫자를 동봉하여 가지고 있는 셈이 된 것이다. 그래서 더하기1 이라는 함수에 숫자 1을 매개변수로 넘겨주며 호출을 하게 되면 기존 부모함수 더하기함수공장 이라는 함수에 동봉되어 있던 매개변수 1, 그리고 더하기1 함수에 매개변수로 넘겨준 1의 덧셈값이 덧셈 함수의 리턴값이 되게 되며, 최종적으로 덧셈 함수를 리턴하였으므로 2가 리턴이 된다.
출처 - 생활코딩 유튜브
피드백은 환영입니다!! 항상 발전하려고 하는 미래의 주니어 개발자입니다.