HyunJun 기술 블로그

Scope 본문

JavaScript

Scope

공부 좋아 2023. 7. 5. 08:51
728x90
반응형

0. 스코프 (Scope)

스코프에는 아래와 같은 종류가 있다.

  • 전역 스코프 (global scope)
  • 지역 스코프 (local scope)
    • 함수 스코프 (function level scope)
    • 블록 스코프 (block level scope)

 

1. 전역 스코프 (global scope)

블록 "{}"과 함수를 제외한 곳에서 선언된 변수의 스코프를 의미한다. global에서 선언된 전역 스코프 변수는 전역과, 지역 내에서도 사용 및 변경이 가능하다.

  let a = 1;

  {
    console.log(a++);
  }

  function test() {
    console.log(a++);
  }

  test();

  console.log(a++);

 

2. 지역 스코프 (local scope)

1) 함수 스코프 (function level scope)

함수 내에서 선언된 변수는 해당 함수 내에서만 사용 및 변경이 가능하다.

  function test() {
    let a = 1;
  }
  test()
  // console.log(a);

 

2) 블록 스코프 (block level scope)

블록 내에서 선언된 변수는 해당 블록 내에서만 사용 및 변경이 가능하다. 또한, 지역 내에서 전역 변수의 값을 수정할 수 있으며, 같은 이름의 지역 변수를 선언하면 해당 지역 내에서만 적용된다. 참고로 if, for, while, switch 등의 코드 블록은 블록 스코프이다.

  let a = 1;
  {
    let b = 2;
    a = "a";
    console.log(b);
    console.log(a);
  }

  // console.log(b);
  console.log(a);

(왼쪽) 결과, (오른쪽) 지역에서 선언된 변수를 전역에서 사용하려고 할 경우

 

 

3. 심화

3-1. 블록, 함수 스코프에서의 전역 스코프 변수 사용.

  • 블록, 함수 스코프에서의 전역 스코프 변수 접근은, 전역 스코프에 있는 변수와 같은 이름으로, 재 선언을 하는 경우 블록(함수) 내부에서만 사용되는 지역 변수로 사용되고, a = "a"와 같이 사용하면 전역 스코프에 변수가 있다면 해당 변수에 접근하여 사용하고 없다면 window의 프로퍼티로 들어가게 된다.
  let a = 1;
  let b = 2;
  let c = 3;

  {
    a = "a";
    let b = "b";
    console.log(a);
    console.log(b);
  }

  function test() {
    let a = 1;
    c = "c";

    console.log(a);
    console.log(c);
    d = "d";
  }

  test();
  console.log(a);
  console.log(b);
  console.log(c);

  console.log(window);

(왼쪽) 결과, (오른쪽) window 객체의 프로퍼티로 저장된 "d"

 

 

 

3-2. var, let, const

스코프의 경우 단순히 선언을 하는 위치도 중요하지만, var, let, const 등 무엇으로 선언하냐에 따라서의 차이도 있다. var는 함수 스코프(function level scope)이다. 이 말은 함수 내에서 사용될 때에만 해당 지역의 스코프를 가지게 되고, 블록 스코프 및 전역 스코프에서 선언된다면 window 객체로 들어가 전역 변수와 같이 동작한다. 이때 var를 생략한 변수의 경우에도 window 객체에 들어가게 되는데 단순히 var가 생략된 것처럼 생각할 수 있다 하지만, 이는 window의 프로퍼티로 들어가는 것으로 var 키워드와 var 키워드를 생략하고 만든 변수에는 분명한 차이가 있다.

 

 

1) var는 블록 혹은 전역에서 선언 시 window 객체에 저장되어 전역변수와 같은 역할을 한다.

  var a = 1;
  {
    var b = 2;
  }

  console.log(window);

 

 

2. 하지만, 함수 내에서 선언 시 지역 변수로 동작한다.

즉, var와 var를 생략한 것은 결과적으로 다른 결과를 낸다.

  function testA() {
    var a = 1;
  }

  function testB() {
    b = 2;
  }

  testA();
  testB();


  console.log(window);

 

3-3. 호이스팅

아래의 코드를 확인해 보자.

  let a = 1;
  {
    console.log(a);
    // let a = 2;
    // var a = 3;
  }
  • let a = 2; let은 블록 스코프를 가지며, 블록 내에서 호이스팅 되지만 let이기 때문에 undefined 값을 넣어주지 않게 되고 에러가 발생한다.

이는 변수가 아예 존재하지 않을 때 발생하는 Uncaught ReferenceError: a is not defined 에러와는 차이가 있다. == 호이스팅이 발생한다.

 

  • var a = 3; var는 함수 스코프를 가지기 때문에, 블록에서 선언하게 되면,  블록 외부에서도 유효하게 window 객체 아래에 전역 변수로 등록된다. 하여 이미 전역 변수로써 사용되는 a가 있기 때문에 에러가 발생한다.

 

3-4. 전역 변수 사용하기.

잘 사용하지는 않지만 전역 변수를 사용하여 극단적으로 아래와 같이 사용할 수도 있다.

// 전역 스코프 변수를, 지역 스코프에서 사용 가능
let i = 10;
for (; i > 0; i--) {
  console.log(i);
}


// 극단적으로 아래처럼도 사용 가능.
let j = 10;
for (;;) {
  console.log(j);
  --j;
  if (j == 0) break;
}
728x90
반응형
Comments