스코프 (체인)은 함수에서 어떤 값에 접근이 가능/불가능 한가 따져볼 때 사용되는 개념이다.
이때 판별하는 범위는 블록 단위인데, 블록은 중괄호로 감싸여진 범위다.
const x = "x";
function c() {
const y = "y";
console.log("c");
function b() {
const z = "z";
console.log("b");
c();
}
}
function a() {
const x = "x";
console.log("a");
b(); // b를 선언 안했다는 ERROR
}
a();
c();
위 코드를 실행하면 함수 a 안에 있는 b를 호출할 때 b를 선언하지 않았다는 에러가 발생한다.
b가 a의 스코프 범위 안에 있지 않기 때문이다.
스코프 범위에 있는지 확인하려면 함수 선언을 기준으로 최상위에 있냐/아니냐를 따져보면 알기 쉽다.
c -> anonymous
a -> anonymous
b -> c -> anonymous
앞서 호출 스택 글에서 anonymous는 파일 전체를 뜻하는 함수라고 생각하면 된다고 했다.
위에 작성한 관계를 풀어서 설명해보자면,
c와 a는 anonymous 함수 안에 있고, b는 c 안에 있다.
이러한 관계를 렉시컬 스코프(어휘적 범위)라고 한다.
a기준 b는 not defined지만, b기준에서 a에 접근 가능하다.
타고타고 올라가서 anonymous 함수까지 가는데 이 함수 안에는 a가 있어서 가능한 것이다.
이를 코드에서 직관적으로 바로 따져보고 싶다면, 들여쓰기를 잘 했다는 가정하에 함수 '선언'을 기준으로 위로 쭉 올라가보면 된다. 만약 다른 선언에서 걸린다면 해당 함수가 부모함수다.
아래 그림에서는 b가 c에서 걸리니 c의 부모함수이고, c와 a는 막힘없이 끝까지 올라가므로 anonymous가 부모 함수임을 알 수 있다.
하지만 코드가 길어지면 이렇게 하나하나 올라가 보긴 힘들 것이다.
이럴때 선언에 대한 지도를 그려보면 직관적으로 알 수 있다. (익숙해지면 머릿속으로도 그려진다고 한다.)
anonymous -> x, c, a
c -> y, b
b -> z
a -> x
위 관계를 풀어 설명해보자면, anonymous가 선언한건 x, c, a가 있고, c는 y, b를 선언했다는 것이다.
즉 어떤 함수에서 어떤 것이 선언됐는지 그려본 것이다.
여기서 x라는 같은 이름의 변수가 2개가 있는데, 같은 이름이어도 위치가 다르면 사용할 수 있다.
a함수에서 x 변수를 사용할때는, a를 먼저 보고 anony를 확인하기 때문이다.
애초에 위 코드에서는 a안에 있는 x변수를 먼저 찾아냈으니 anony까지 찾아보러 갈 일이 없다. 그러므로 문제 없이 쓸 수 있다.
참고: 제로초 '인간 JS 엔진되기' 강좌를 보고 정리한 글입니다.
'JavaScript' 카테고리의 다른 글
JavaScript 원시 타입 종류 7가지 (0) | 2024.08.02 |
---|---|
변수는 왜 필요한가?, 어떻게 선언되고 할당되는지도 알아보자 (feat. 메모리) (0) | 2024.07.31 |
호출 스택 분석하는 법 (1) | 2023.02.02 |
함수 호출한 것을 보면, 그 자리에 return한 값을 대체해보자. (0) | 2023.01.31 |
함수 사용하기 - 계산기 (고차 함수 사용, if 문 중첩 제거) (0) | 2023.01.21 |