스코프가 뭐였지...

jaehan·2023년 3월 21일
0

JavaScript

목록 보기
18/33
post-thumbnail
post-custom-banner

지금까지 스코프는 변수의 범위라고 알고 있었기 때문에 다 안다고 생각했었다.
근데 어떤 자료를 읽다보니 렉시컬 스코프(?) 라는 단어를 보고 다시 공부해야 되곘다 싶어 공부해 봤다...

Scope

scope의 한국어 뜻은 범위이다
뜻 자체로 scope는 변수에 접근할 수 있는 범위이다.

전역 / 지역 변수

자바스크립트에는 전역, 지역 변수가 있다.

📌 어차피 이제 var는 안쓰니까 let으로 (블록레벨 스코프)로 설명하겠다.

let a = "global";

function localFunc() {
  let a = "local";
  a = "change value";
  
  console.log(a);
}

localFunc(); // 1
console.log(a); // 2

위 코드를 보면

  • 첫번째 a는 전역 스코프이고
  • 두번째 a는 지역스코프이다.

let은 블록레벨 스코프를 따르는 변수이기 때문에 {}내부에 있는 변수를 지역변수로 칭한다.

그래서 위 코드의 결과는
1️⃣ localFunc() -> "change value"

  • {} 내부에서 let으로 변수를 선언했기 때문에 지역변수이다.
  • 이 변수는 밖의 a와는 아예 다른 변수이다
  • 그렇기 때문에 {}내부에서 a를 호출하면 블록내부의 변수를 가져와서 사용한다.

2️⃣ console.log(a) -> "global" 이다

  • 첫째 줄의 a변수는 전역 변수이다.
  • 따라서 a를 호출하면 같은 범위 내의 a 변수를 가져와서 사용한다.

스코프 체인

let a = "global";

function localFunc() {
  a = "change value";
  
  console.log(a);
}

localFunc(); // 1
console.log(a); // 2

방금 코드에서 지역변수 a를 선언을 안했다고 생각해보자

그럼 결과는
1️⃣ localFunc() -> "change value"

  • 같은 블록 내에 a라는 변수가 없기 때문에 밖의 블록의 a를 가져와서 값을 재할당 한다.

2️⃣ console.log(a) -> "change value" 이다

  • localFunc() 안에서 값을 바꿨기 때문에 바뀐 값을 출력한다.

📌 이것처럼 같은 범위내에 가져오려는 변수가 없으면 변수를 찾을 때 까지 외부 범위로 나가는 걸 스코프 체인이라고 한다.
❗️내부 범위로는 절대 못가고 외부에도 변수가 없으면 변수를 찾지 못했다는 에러가 발생한다.

렉시컬 스코프

❓ 그래서 내가 처음들어봤던 렉시컬 스코프는 뭐냐

우선 가장 중요한 개념이 있는데 ❗️스코프는 함수를 호출할 때가 아니라 선언할 때 생긴다❗️

이게 무슨 말이냐면 아래 코드를 보면 된다.

분명 내 생각으로는 log()가 wapper 내부에서 호출되기 때문에 wrapper 내의 name을 참조하지 않을까? 라고 생각했다.

그럼 결과가 nero여야 하는데 zero네?

이게 바로 렉시컬 스코프다.

무슨말이냐면 스코프는 함수를 선언할 때 생기기 때문에 log 함수를 선언할때 name 변수를 찾을텐데 현재 블록 범위에 없기 때문에 외부의 전역변수 name을 참조하게 되는거다.

그래서 이미 전역변수 name을 사용하기로 마음먹었기 때문에 wrapper 내부에서 호출해도 전역변수를 사용한다.

👍 드디어 렉시컬 스코프가 뭔지 알아냈다. 근데 log가 wrapper의 지역변수 name을 참조하게 할 수는 없을까 했는데 이건 실행 컨텍스트(?)를 이용하면 된다고 한다.

마무리

전역변수는 변수가 섞이게 될 수도 있기 때문에 지양하라고 하기 때문에 최대한 블록 범위를 작게 해서 변수를 선언해야 겠다.

그리고 실행 컨텍스트도 공부해야겠다...

참고 : https://www.zerocho.com/category/JavaScript/post/5740531574288ebc5f2ba97e
모던 자바스크립트 deep dive

post-custom-banner

0개의 댓글