스코프

Leekimoon·2022년 6월 6일
0

💡 스코프(Scope)란?

스코프는 참조 대상 식별자(identifier, 변수, 함수의 이름과 같이 어떤 대상을 다른 대상과 구분하여 식별할 수 있는 유일한 이름)를 찾아내기 위한 규칙이다.
자바스크립트는 이 규칙대로 식별자를 찾는다.

1. 스코프 구분

1) 전역 스코프 & 전역 변수
- 코드 어디에서든지 참조 할수 있는 스코프 & 변수
2) 지역 스코프 & 지역 변수
- 지역(함수) 내에서 선언되어 그 지역과 하위 함수에서만 참조 할수있는 스코프 & 변수

2. JS 스코프 특징

대부분의 C-family language는 블록 레벨 스코프(block-level scope)를 따른다.
하지만 자바스크립트는 함수 레벨 스코프(function-level scope)를 따른다.

단, ECMAScript 6에서 도입된 let keyword를 사용하면 블록 레벨 스코프를 사용할 수 있다.
var x = 0;
{
  var x = 1;
  console.log(x); // 1이 출력
}
console.log(x);   // 함수 레벨 스코프 특징으로 1이 출력

let y = 0;
{
  let y = 1;
  console.log(y); // 1
}
console.log(y);   // let 키워드는 값이 변경되지 않는다.

3. 전역 스코프

전역에 변수를 선언하면 이 변수는 어디서든지 참조할 수 있는 전역 스코프를 갖는 전역 변수가 된다.
var 키워드로 선언한 전역 변수는 전역 객체(Global Object) window의 프로퍼티이다.

var global = 'global';

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

console.log(global); //함수 밖에서 언제든 조회가 가능하다
console.log(local); // Uncaught ReferenceError: local is not defined

주의사항
전역 변수의 사용은 변수 이름이 중복될 수 있고, 의도치 않은 재할당에 의한 상태 변화로 코드를 예측하기 어렵게 만드므로 사용을 억제하여야 한다.

3-1. 비 블록 레벨 스코프(Non block-level scope)

자바스크립트는 블록 레벨 스코프를 사용하지 않으므로 함수 밖에서 선언된 변수는 코드 블록 내에서 선언되었다할지라도 모두 전역 스코프을 갖게된다. 따라서 변수 x는 전역 변수이다

if (true) {
  var x = 5;
}
console.log(x); //5를 출력

4. 함수 레벨 스코프

var a = 10;     // 전역변수

(function () {
  var b = 20;   // 지역변수
  console.log(a); // 10
  a = 100; // 전역변수 값 변경 가능
  function() {
    b = 200;
    console.log(b) // 200 출력
  }
})();

console.log(a); // 100
console.log(b); // "b" is not defined

특징

  • 함수 내에서 선언된 매개변수와 변수는 함수 외부에서는 유효하지 않다.
  • 함수 내 지역 영역에서는 전역과 지역 변수 모두 참조 가능하나 변수명이 중복된 경우, 지역변수를 우선하여 참조한다.
  • 내부함수는 자신을 포함하고 있는 외부함수의 변수에 접근할 수 있다. 이는 매우 유용하다. 클로저에서와 같이 내부함수가 더 오래 생존하는 경우, 타 언어와는 다른 움직임을 보인다.
  • 내부 함수의 경우, 전역변수는 물론 상위 함수에서 선언한 변수에 접근/변경이 가능하다.

5. 렉시컬 스코프

렉시컬 스코프는 함수를 어디서 호출하는지가 아니라 어디에 선언하였는지에 따라 결정된다.
첫번째 방식을 동적 스코프(Dynamic scope)라 하고, 두번째 방식을 렉시컬 스코프(Lexical scope) 또는 정적 스코프(Static scope)라 한다. 자바스크립트를 비롯한 대부분의 프로그래밍 언어는 렉시컬 스코프를 따른다.

var x = 1;

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

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

foo(); // 1 (첫번째 방식)
bar(); // 1 (두번째 방식)

6. 암묵적 전역

var x = 10; // 전역 변수

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

delete y;

foo(); // 30

foo 함수의 스코프와 전역 스코프 어디에서도 변수 y의 선언을 찾을 수 없으므로 참조 에러가 발생해야 하지만 자바스크립트 엔진은 y = 20을 window.y = 20으로 해석하여 프로퍼티를 동적 생성한다. 결국 y는 전역 객체의 프로퍼티가 되어 마치 전역 변수처럼 동작한다. 이러한 현상을 암묵적 전역(implicit global)이라 한다.
다만 y는 변수 선언없이 단지 전역 객체의 프로퍼티로 추가되었을 뿐 이어서 y는 변수가 아니다. 따라서 변수가 아닌 y는 변수 호이스팅이 발생하지 않는다.
=> 변수가 아니라 단지 프로퍼티인 y는 delete 연산자로 삭제할 수 있다.

7. 즉시실행함수를 이용한 전역변수 사용 억제

전역변수 사용을 억제하기 위해, 즉시 실행 함수(IIFE, Immediately-Invoked Function Expression)를 사용할 수 있다. 이 방법을 사용하면 전역변수를 만들지 않으므로 라이브러리 등에 자주 사용된다.
즉시 실행 함수는 즉시 실행되고 그 후 전역에서 바로 사라진다.

(function () {
var MYAPP = {};

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

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

console.log(MYAPP.student.name); //Uncaught ReferenceError: MYAPP is not defined
	
profile
FrontEnd Developer

0개의 댓글