본문 바로가기

2주차

[JS] 스코프(Scope)

 

안녕하세요:) 웹 파트 YB 유서연입니다!

 

이번 글에서는 2주차 세미나 내용 중 흥미로웠던 '스코프'에 대해 알아보겠습니다.


스코프란?

function add(x,y) {
  console.log(x, y); // 2 5
  return x + y;
 }

add(2, 5);

console.log(x, y); // ?

 

위 코드에서 함수 add 외부의 console.log(x, y);는 무엇을 출력할까요?

우리는 ReferenceError를 발생시킬 것이라 예상할 수 있습니다.

왜냐하면, x와 y 값은 함수를 호출할 때 지정하는 매개변수이므로 함수 내부에서만 참조할 수 있기 때문이죠.

이처럼 변수를 참조할 수 있는 유효 범위를 '스코프'라고 합니다.

 

자바스크립트 엔진은 스코프를 통해 어떤 변수를 참조해야 할 것인지 결정합니다.

따라서, 스코프는 "식별자를 검색하는 규칙"이라고도 할 수 있습니다.

✏️ 스코프 : 식별자를 참조할 수 있는 유효 범위, 식별자를 검색하는 규칙

 

 

💡 var 키워드로 선언한 변수의 중복 선언

function foo () {
  var x = 1;
  var x = 2;
  console.log(x); // 2
 }
 
foo();

 

var 키워드로 선언된 변수는 같은 스코프 내에서 중복 선언을 허용합니다.

이에 따라 의도치 않게 변수값을 재할당하는 문제가 발생할 수 있습니다.

이러한 문제를 해결하는 것이 let과 const 입니다.

let이나 const 키워드로 선언된 변수는 같은 스코프 내에서 중복 선언을 허용하지 않습니다.

 

스코프의 종류

자바스크립트에서 스코프는 크게 전역 스코프지역 스코프로 구분할 수 있습니다.

1. 전역 스코프 (Global Scope)

  • 전역 : 코드의 가장 바깥 영역
  • 전역 변수는 어디서든지 접근이 가능하여 코드 전역에서 참조할 수 있습니다.

2. 지역 스코프 (Local Scope)

  • 지역 : 함수 몸체 내부
  • 지역 변수는 선언된 함수 내부 또는 해당 지역 스코프와 그 하위 스코프에서만 유효합니다.

 

스코프 체인 (Scope Chain)

✏️ 스코프 체인 : 스코프가 함수의 중첩에 의해 하나의 계층적 구조로 연결된 것

 

변수를 참조할 때 자바스크립트 엔진은 스코프 체인을 통해 변수를 참조하는 코드의 스코프에서 시작하여 상위 스코프 방향으로 이동하며 선언된 변수를 검색합니다.

위 그림에서 inner 함수는 x 변수를 참조할 때 자신의 스코프에 존재하지 않으므로 상위 스코프 방향으로 이동하며 변수를 검색합니다.

 

함수 레벨 스코프 vs 블록 레벨 스코프

 

자바스크립트에서 var 키워드로 선언된 변수는 함수 레벨 스코프를 가집니다.

이는 코드 블록 {} 내에서 선언되더라도 블록 바깥에서 유효하다는 의미입니다.

반면, let과 const는 블록 레벨 스코프를 가지며, 선언된 코드 블록 내에서만 유효합니다.

 

  • 함수 레벨 스코프 : var 키워드로 선언된 변수는 오로지 함수의 코드 블록(함수 몸체)만을 지역 스코프로 인정
var x = 1;

if (true) {
  var x = 10;
}

console.log(x); // 10

 

위 코드에서 x는 코드 블록 내에서 재선언되었지만, var는 함수 레벨 스코프를 따르므로 x 변수가 전역에서 참조됩니다.

 

  • 블록 레벨 스코프 : 대부분의 프로그래밍 언어는 모든 코드 블록({})을 지역 스코프로 인정
let y = 1;

if (true) {
  let y = 10;
}

console.log(y); // 1

 

let을 사용한 위의 코드에서 y는 블록 스코프 내에서만 유효하므로 코드 블록 바깥의 y는 1 입니다.

 

렉시컬 스코프 (Lexical Scope)

상위 스코프를 결정하는 방식으로는 두 가지가 있습니다.

  1. 동적 스코프 : 함수를 어디서 호출했는지에 따라 함수의 상위 스코프 결정
    • 함수가 호출되는 시점에 동적으로 상위 스코프를 결정합니다.
  2. 렉시컬 스코프 (정적 스코프) : 함수를 어디서 정의했는지에 따라 함수의 상위 스코프 결정
    • 함수 정의가 평가되는 시점에 상위 스코프가 정적으로 결정됩니다.

자바스크립트는 "렉시컬 스코프"를 따릅니다.

이는 함수가 정의된 위치에 따라 상위 스코프가 결정되며, 호출 위치는 상위 스코프 결정에 영향을 주지 않는다는 의미입니다.

 

var x = 1;
function foo(){
  var x = 10;
  bar();
}

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

foo(); // 1
bar(); // 1

 

위 코드에서 bar 함수는 foo 함수 내에서 호출되었지만, 상위 스코프는 함수가 정의된 위치에 따라 전역 스코프입니다.

따라서, 전역 변수 x의 값인 1이 두 번 출력됩니다.