FrontEnd/JavaScript

Modern JavaScript 스코프

is..cy 2023. 1. 22. 12:50

 


 

1. 스코프

  • 스코프 :  참조 대상 식별자(identifier) 를 찾아내기 위한 유효범위
  • 어디에 선언 되었는지 정해진 범위에 대한 규칙
  • 식별자 이름의 충돌을 방지한다.

 


 

2. 스코프의 구분

  • 전역 스코프 (Global scope) : 코드 어디에서든 참조
  • 지역 스코프 (Local scope/ function-level scope) : 함수 코드 블록이 만든 스코프로 자신과 하위함수에만 참조
  • 전역 변수 (Global variable) : 어디서든 참조 가능한 변수 (전역에서 선언)
  • 지역 변수 (Local variable) : 해당 함수와 하위 지역에서만 참조 (함수 내에서 선언된 변수)

 


 

3. 스코프 특징

 

  • 블록 레벨 스코프 (block-level scope) : ({...}) 코드블록 내에서 유효한 스코프 (코드플록 내에서 접근 가능)

     - C-family Language

     - Javascript : Non block-level scope, 함수 밖에 선언된 변수는 블록 내에 선언되어도 전역스코프임

int main(void) {
  // block-level scope
  if (1) {
    int x = 5;
    printf("x = %d\n", x);
  }

  printf("x = %d\n", x); // use of undeclared identifier 'x'

  return 0;
}

 

  • 함수 레벨 스코프 (function-level scope) : 함수 코드내에서만 유효 (함수 외부에서는 유효 x) 

      - javascript : 시작점이 따로 없어 전역변수를 남용할 가능성이 있다. 할당상태 변화시 예측이 어려우므로 제어가 필요

      - 함수 내에서 선언된 매개변수와 변수는 함수 외부에서는 유효하지 않음

 

var x = 'global';

function foo() {
  var x = 'local';
  console.log(x);
}

foo();          // local
console.log(x); // global

 

        - 전역변수와 지역변수 변수명이 중복선언 될시, 지역변수를 우선하여 참조 

 

 

var foo = function ( ) {

  var a = 3, b = 5;

  var bar = function ( ) {
    var b = 7, c = 11;

// 이 시점에서 a는 3, b는 7, c는 11

    a += b + c;

// 이 시점에서 a는 21, b는 7, c는 11

  };

// 이 시점에서 a는 3, b는 5, c는 not defined

  bar( );

// 이 시점에서 a는 21, b는 5

};

       - 중첩 스코프는 가장 인접한 지역을 우선하여 참조 : 실행 컨텍스트의 스코프 체인에 의해 참조순위가 변경된다.

 

  • 렉시컬 스코프 (Lexical scope) : 함수를 어디에 선언하였는지에 따라 결정 (javascript)
  • 동적 스코프 (Dynamic scope) : 함수를 어디서 선언하였는지에 따라 결정

 


 

4. 암묵적 전역 (implicit global)

var x = 10; // 전역 변수

function foo () {
  // 선언하지 않은 식별자
  y = 20;
  console.log(x + y);
}

foo(); // 30

- y가 선언되지 않았지만 마치 선언된것처럼 동작 (선언하지 않은 식별자에 값 할당시 객체의 프로퍼티로 바뀜)

- 전역변수는 delete  연산자로 삭제할 수 없다. (프로퍼티만 가능, delete y)

 


 

5. 변수 통제

  • 최소한의 전역변수 사용 : 전역 변수 객체를 하나 만들어 사용
var MYAPP = {};

MYAPP.student = {
  name: 'Lee',
  gender: 'male'
};

console.log(MYAPP.student.name);

 

  • 즉시실행함수(Immediately-Invoked Function)를 이용하여 전역변수 사용 억제 : 즉시실행후 전역에서 사라진다.

        - 라이브러리에 자주 사용

 

(function () {
  var MYAPP = {};

  MYAPP.student = {
    name: 'Lee',
    gender: 'male'
  };

  console.log(MYAPP.student.name);
}());

console.log(MYAPP.student.name);