⚡️⛓J 시각적인 자바스크립트 : 스코프 (체인)

👊0👊·2020년 2월 1일
0

(https://dev.to/lydiahallie/javascript-visualized-scope-chain-13pd) 글을 번역했습니다.

스코프 체인을 위한 시간이다 🕺🏼 이 포스트는 기본적으로 실행 컨택스트의 기본을 알고있다고 가정한다. 그러나 곧 실행 컨텍스트에 대해서 포스트를 쓸 것이다. 😃

다음의 코드를 보자.

const name = "Lydia"
const age = 21
const city = "San Francisco"


function getPersonInfo() {
  const name = "Sarah"
  const age = 22

  return `${name} is ${age} and lives in ${city}`
}

console.log(getPersonInfo())

우리는 getPersonInfo 함수를 호출했다. 그리고 nameage, city 변수들의 값들을 포함하는 문자열(Sarah is 22 and lives in San Francisco)을 반환한다. 하지만 getPersonInfo 함수는 city변수를 갖고 있지 않는다🤨? 어떻게 city 값을 알고 있을까?

우선, 메모리 공간이 다른 컨텍스트들을 위해 설정(set up)되었다. 우리는 두 가지 컨택스트를 가지고 있다. 기본 글로벌 컨택스트(global context)(브러우저에선 window, Node에선 global), 그리고 호출되는 getPersonInfo함수를 위한 로컬 컨택스트(local context)이다. 각 컨택스트는 역시 각각의 스코프 체인이 있다.

getPersonInfo함수를 위해서, 스코프체인은 이와 같이 보인다.(걱정마라, 아직은 이해가 안가도 된다.)

3-1.png

스코프체인은 기본적으로 오브젝트들(objects)에 대한 "참조의 체인(chain of references)"이다. 객체들은 실행 컨택스트(execution context)안에서 참조할 수 있는 값들(또는 다른 스코프)에 대한 참조를 포함한다. (⛓: "이봐, 여기엔 모두있어구. 이 컨텍스트 안에서 참조할 수 있는 것들 말이야.") 실행 컨텍스트가 생성 될때 스코프 체인이 생성된다, 즉 실행(runtime)중에 생성된다!

그렇지만, 이 포스트에서는 활성 객체(activation object)나 실행 컨택스트를 이야기하고 싶지않다. 스코프에만 집중하자!. 다음 예제에선, 실행 컨택스트에서 키/값 쌍이 참조들로 나타난다. 이 참조들은 스코프체인이 갖는 변수들이다.

iala2et7bg9bgdj4c2lg.png

전역 실행 컨텍스트(global execution context)는 3가지 변수들에 대한 참조를 가지고 있다. Lydia값을 가지고 있는 name, 21값을 가지고 있는 age, San francisco값을 가지고 있는 city.
지역 콘텍스트(local context)에서는, 2가지 변수들에 대한 참조를 가지고 있다. Sarah값을 가지고 있는 name, 22값을 가지고 있는 age.

우리가 getPersonInfo함수 안에 있는 변수들에 접근할 때, 엔진은 처음으로 지역 스코프 체인을 검사한다.

xn17f0t54acz8tiq7122.gif

지역 스코프 체인은 nameage에 대한 참조를 가지고 있다! nameSarah란 값을 가지고 있고, age22의 값을 가지고 있다. 하지만 city에 접근하려고 할 때 무슨일이 벌어날까?

city의 값을 찾기위해서, 엔진은 "스코프 체인을 따라 내려간다". 이건 기본적으로 엔진이 쉽게 포기하지 않는다는 것을 의미한다. 지역 스코프가 참조하는 밖의 스코프(outer scope)(이 경우에선 전역 객체(global object))안의 변수 city에 대한 값을 찾기 위해 열심히 노력한다.

z9iclg23rmbpts7meoq6.gif

전역 컨텍스트에선, San Francisco를 가지고 있는 변수 city는 선언되었다, 그래서 city변수에 대한 참조를 가지고 있다.
지금 변수들에 대한 값을 가지고 있다, 함수 getPersonInfo는 문자열 Sarah is 22 and lives in San Francisco를 반환한다.🎉

우리는 스코프 체인을 따라 내려갈(go down) 수 있지만, 스코프체인을 올라갈(go up) 수는 없다.(맞다, 이건 아마 혼란스러울 것이다. 왜냐하면 몇몇 사람들은 올라간다는 말대신 내려간다고 하기도 한다, 그래서 다시 말하자면, 밖의 스코프(outer scopes)로 갈 수 있다고 한다. 하지만 안으로(inner)는 갈 수 없다....(안으로(inner)...?). 나는 이것이 일종의 폭포 같이 시각화하고 싶다.

doq46yc6nuiam51evy44.png

또는 깊어진다.

rece2zj4pb4w1fn56q5k.png

이제 코드로 예제를 보자.

0z6342b72f3n6v6ufafk.png

이건 거의 똑같지만, 큰 차이점 하나가 있다. 오직 getPersonInfo안에서 city는 선언된다. 그리고 전역스코프에는 선언되지 않는다. 우리는 getPersonInfo 함수를 호출하지 않는다. 그래서 지역 컨택스트 또한 생성되지 않는다. 그러나, 글로벌 컨택스트에서 name ,age,city에 접근하려고 한다.

f3wvlo4c3gqf3mve1g0n.gif

ReferenceError를 뱉는다! 글로벌 컨택스트에선 city라고 불리는 변수에 대한 참조를 찾을 수 없다, 그리고 찾을 수 있는 밖의 스코프도 없고, 스코프 체인을 올라갈 수 없다.

이런식으로, 변수들을 "보호"하고 변수명을 재사용하는 방법으로 스코프를 사용할 수 있습니다.


또한 전역과 지역 스코프말고, 블록 스코프(block scope)라고 있습니다. let이나 const 키워드로 선언되는 변수들은 가장 가까운 중괄호({})로 범위(scoped)지어진다.

const age = 21

function checkAge() {
  if (age < 21) {
    const message = "You cannot drink!"
    return message
  } else {
    const message = "You can drink!"
    return message
  }
} 

스코프를 시각화할 수 있다.

75n1vpm7z4d8924cnvje.png

코드에선 전역 스코프, 함수 스코프, 두 가지 블록 스코프를 가진다. 변수 message는 두 번 선언되어 진다, 변수들이 중괄호 스코프로 범위지어기지 때문이다.

빠르게 되돌아보자.

  • 이제 "스코프 체인"을 현재 컨텍스트에서 접근할 수 있는 값들에 대한, 참조들의 체인으로 볼 수 있게 되었다.
  • 스코프는 또한, 변수명들을 재사용할 수 있게 한다. 변수명들은 스코프체인 아래로 정의되어진다, 스코프체인 아래로 갈 수 있지만, 위로는 못가기 때문이다.

스코프(체인)이었다!. 이것에 대해서 더 많은 이야기 할 수 있으므로 편한 시간에 정보를 추가할 수 있다. 무엇이든 어려움을 겪고 있으면 편하게 물어보라, 나는 돕는 것을 좋아한다!💕

profile
ㅎㅎ

0개의 댓글