스코프

코딩덕·2023년 12월 18일

💡 JS 스코프

가끔식 코딩을 하다보면 특정 변수값이 중복되는지 헷갈릴때가 있다..
스코프에 대해 정확히 이해한다면 복잡하고 장황한 코드에서 중복명의 변수,함수를 자유롭게 선언하고 사용할 수 있기 때문에 꿀이다.

JavaScript에서 스코프란 식별자가 유효한 범위를 말한다
쉽게 말해 특정 변수,함수,클래스 등에 접근할 수 있는 범위라고 볼 수 있다

스코프는 크게 전역스코프(global)과 지역스코프(local)로 나뉜다.

  • 전역 : 코드 가장 바깥영역의 식별자(어디서든지 참조가능)

  • 지역 : 함수 몸체내부 식별자(자신과 하위 스코프에서 참조가능)

var a = 1; // 전역 스코프

function print() { 
  var a = 111; // 지역 스코프
  console.log(a); 
}

print(); // 111 출력
console.log(a); // 1 출력

스코프 체인 ⛓️

스코프들이 계층적으로 연결 된 것

실행 컨텍스트 내부에서 Outer Environment Reference(외부 환경 참조)를 통해 구현된다.

JS는 변수,함수(식별자) 값을 얻으려고 할 때 스코프 체인에서 찾는다.

첫 번째 객체에서 해당 변수를 찾고, 없으면 그 다음 객체에서 해당 변수를 찾고, 여기도 없으면 그 다음 객체에서 찾는다. 끝까지 탐색했는데도 그 변수가 없다면 reference error가 발생하게 된다.

즉, 스코프는 변수를 참조한 스코프부터 시작해, 상위 스코프로 이동하며 변수값을 찾는다!

// 전역함수
let globalVar = "I'm global";

function outer() {
  let outerVar = "I'm in outer";

  function inner() {
    let innerVar = "I'm in inner";

    console.log(innerVar); // ✅ 현재 스코프에서 찾음 → "I'm in inner"
    console.log(outerVar); // ✅ 현재 스코프에 없으므로 상위 스코프(outer)에서 찾음 → "I'm in outer"
    console.log(globalVar); // ✅ 현재 스코프 → outer 스코프 → 전역 스코프에서 찾음 → "I'm global"
    console.log(unknownVar); // ❌ ReferenceError (어디에서도 찾을 수 없음)
  }

  inner();
}

outer();

렉시컬 스코프

JS는 함수가 선언될 때마다 상위 스코프를 기억한다. 값을 참조해야 할 수 있기 때문이다.

렉시컬 스코프는 상위 스코프가 결정되는 방식으로,
함수를 선언한 위치에 따라 상위 스크프를 결정한다.

🔥 함수의 호출위치는 중요하지 않다, 선언위치가 중요할 뿐!! 🔥

자바스크립트를 비롯한 대부분의 언어는 렉시컬 스코프를 따른다
아래 헷갈리는 예제를 보자..

let x = "global";

function foo() {
  let x = "foo";
  bar();
}

function bar() {
  console.log(x);
}

foo(); // "global"

함수 스코프, 블록 스코프

  • 함수 스코프 : var 로 선언한 변수는 오로지 함수의 코드 블록만을 지역 스코프로 인정

  • 블록 스코프 : letconst로 선언한 변수는 모든 코드 블록(중괄호)를 지역 스코프로 인정


함수레벨 스코프

var x = 10;

// if문은 함수가 아니므로 지역 스코프로 인정 X 
// *뭔짓을 해도 위의 x값은 바뀜*
if(true){
  var x = 20;
  console.log(x);  // 20 출력
}

// 함수이므로 지역 스코프로 인정 O 
// *뭔짓을 해도 위의 x값은 안바뀜*
function ex(){
  var x = 97;
  console.log(x);  // 97 출력
}

ex();

console.log(x); // 20 출력(의도치 않게 바뀐 x값)


블록레벨 스코프

let x = 10;

// if문은 중괄호로 감싸져 있으므로 지역 스코프로 인정 O
// *뭔짓을 해도 위의 x값은 안바뀜*
if(true){
  let x = 20;
  console.log(x);  // 20 출력
}

// 함수이므로 지역 스코프로 인정 O
// *뭔짓을 해도 위의 x값은 안바뀜*
function ex(){
  let x = 97;
  console.log(x);  // 97 출력
}


console.log(x); // 10 출력(바뀌지 않은 x값)

🤔 이제 var,let의 차이를 더욱 자세히 알아보자..

0개의 댓글