JavaScript

[모던 자바스크립트] 스코프

jjin502 2022. 7. 5. 19:41

스코프란 ?    

  • 스코프 : 유효 범위
// 13-1
    function add(x, y) {
      // 매개 변수는 함수 몸체 내부에서만 참조할 수 있다.
      // 즉, 매개변수의 스코는 함수 몸체 내부.
      console.log(x, y);
      return x + y;
    }

    add(2, 5);

    // 매개변수는 함수 몸체 내부에서만 참조할 수 있다.
    console.log(x, y);
    // Uncaught ReferenceError: x is not defined
 // 13-2
    // 스코프 : 모든 식별자(변수, 함수, 클래스 이름 등) 자신이 선언된 위치에 의해 다른 코드가 식별자 자신을 참소할 수 있는 유효 범위
    // -> 식별자가 유효한 범위
    var v1 = 1;
    if (true) {
      var v2 = 2;
      if (true) {
        var v3 = 3;
      }
    }

    function foo() {
      var v4 = 4;
      function bar() {
        var v5 = 5;
      }
    }

    console.log(v1);
    console.log(v2);
    console.log(v3);
    console.log(v4); // Uncaught ReferenceError: v4 is not defined
    console.log(v5); // Uncaught ReferenceError: v5 is not defined
// 13-3
    // 식별자 결정 : 자바스크립트 엔진은 이름이 같은 두 변수 중 어떤걸 참조할 것인지 결정함.
    // 식별자를 검색할 때 사용하는 규칙
    var v1 = "global"; // 어디든 참조 가능

    function foo() {
      var v1 = "local"; // foo 함수 내에서만 참조 가능
      console.log(v1);
    }

    foo();
    console.log(v1);

    // local
    // global
  •  26,27번 라인 바뀌면 결과 값도 바뀌어서 나옴
  •  v1은 식별자 이름이 동일하지만, 스코프가 다른 별개의 변수
  • 랙시컬환경 : 코드가 어디에서 실행되며 주변에 어떤코드가 있는지 코드의 문맥으로 이루어져 있음
  • 이를 구현한 것 -> 실행 컨텍스트

 

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

// 13-4
    // 스코프 === 네임스페이스
    // 네임스페이스 : 프로그래밍 언어에서 특정한 객체(Object)를 이름(Name)에 따라 구분할 수 있는 범위를 의미한다.

    function foo() {
      // var 키워드로 선언한 변수는 중복 선언이 가능하다.
      var v1 = 1;

      // 아래  변수 선언은 자바스크립트 엔진에 의해 var키워드가 없는 것처럼 동작한다.
      var v1 = 2;
      console.log(v1);
    }

    foo();

 

// 13-5
    // let,const 키워드로 선언된 변수는 같은 스코프 내에서 중복선언을 허용하지 않는다.
    function foo() {
      // let or const 키워드로 선언한 변수는 중복 선언이 불가능하다.
      let v1 = 1;
      let v1 = 2;
      console.log(v1);
      // Uncaught SyntaxError: Identifier 'v1' has already been declared
    }

    foo();

스코프의 종류

  • 전역 : 코드의 가장 바깥영역 → 어디든지 참조 가능하다.
  • 지역 : 함수 몸체 내부 → 자신의 지역 스코프와 하위 지역스코프에서만 유효함

전역 스코프, 지역 스코프 

  •  함수가 중첩이 가능하므로 지역스코프도 중첩될 수 있다.
  • 스코프가 함수 중첩에 의해 계층적 구조를 가진다.
  • 이때 외부 함수의 지역 스코프를 중첩함수의 상위 스코프라 한다

스코프 체인

  •  스코프 체인 : 스코프가 계층적으로 연결된것.
  • 변수를 참조할 때 자바스크립트 엔진은 스코프 체인을 통해 변수를 참조하는 코드의 스코프에서 시작해 상위 스코프 방향으로 이동하여 선언된 변수를 검색함.
  •  물리적으로 존재한다.
  • 상위 스코프에서 유효한 변수는 하위 스코프에서 자유롭게 참조할 수 있지만, 하위 스코프에서 유효한 변수를 상위 스코프에서 참조할 수 없음
  • 상속과 유사

스코프 체인에 의한 함수 검색

// 13-6
    
    function foo() {
      console.log("g fnc foo");
    }

    function bar() {
      //
      function foo() {
        console.log("l fnc foo");
      }
      foo();
    }

    bar();
    // l fnc foo
    // 함수조 식별자에 할당되기 때문에 스코프를 가짐
    // 따라서 스코프를 식별자를 검색하는 규칙이라고 표현하는게 적함

함수 레벨 스코프 

  •  함수 몸체 내부에서 생성된 스코프 === 지역 스코프
  • 함수 레벨 스코프 : var키워드로 선언된 변수는 오로지 함수의 코드 블록만을 지역스코프로 인정함.
// 13-7
    // 함수 레벨 스코프
   
    var x = 1;
    if (true) {
      // var 키워드로 선언된 변수는 함수의 코드블록만을 지역스코프로 인정
      // 함수 밖에서 var 키워드로 선언된 변수는 코드 블록 내에서 선언되었다할지라도 모두 전역변수임
      // 따라서 x는 전역변수. 이미 선언된 전역변수 x가 있으므로 x변수는 중복 선언됨.
      // 이는 의도치 않게 변수 값이 변경되는 부작용을 발생시킨다.
      var x = 10;
    }

    console.log(x);
// 13-8

    // for문에서 선언한 i는 전역 변수. 이미 선언된 전역변수 i가 있으므로 중복선언.
    var i = 10;

    for (var i = 0; i < 5; i++) {
      console.log(i); // 0 1 2 3 4
    }

    // 의도치 않게 변수의 값이 변경
    console.log(i); // 5

렉시컬 스코프

// 13-9
    // 렉시컬 스코프
    var x = 10;

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

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

    foo();
    bar();
    // bar함수의 상위 스코프가 무엇인지에 따라 결정
    // 1. 함수를 어디서 호출 -> 동적 스코프
    // 2. 함수를 어디서 정의 -> 정적 스코프