Scope

ujin·2022년 11월 20일
0

JavaScript

목록 보기
5/8

Scope란 ?

💡 범위

변수나 함수가 사용될 수 있는 범위

const a = 1

function foo () {
	// 여기는 foo 의 영역입니다.
	const a = 2
	console.log(a) // 2
}

foo()

ES5 일때는 if 나 for 에서 scope가 먹히지 않았다.

ES6 로 업데이트 되면서 가능해졌다. (대신 const ,let 을 사용해야 한다.)

const a = 1

{
	const a = 2
	console.log(a) // 2
}

스코프는 참조 대상 식별자를 찾아내기 위한 규칙이다. 자바스크립트는 이 규칙대로 식별자를 찾는다.

스코프의 구분

  • 전역 스코프 : 코드 어디에서든지 참조할 수 있다.
  • 지역 스코프 : 함수 코드 블록이 만든 스코프로 함수 자신과 하위 함수에서만 참조할 수 있다.

모든 변수는 스코프를 갖는다.

  • 전역 변수 : 전역에서 선언된 변수이며 어디에든 참조할 수 있다.
  • 지역 변수 : 지역 내에서 선언된 변수이며 그 지역과 그 지역의 하부 지역에서만 참조할 수 있다.

변수는 선언 위치에 의해 스코프를 가진다. 즉, 전역에서 선언된 변수는 전역 스코프를 갖는 전역 변수이고, 지역에서 선언된 변수는 지역 스코프를 갖는 지역 변수가 된다.

전역 스코프를 갖는 전역 변수는 전역에서 참조할 수 있다. 지역(함수 내부)에서 선언된 지역 변수는 그 지역과 그 지역의 하부 지역에서만 참조할 수 있다.

자바스크립트 스코프의 특징

대부분은 블록 레벨 스코프를 따른다.

  • 블록 레벨 스코프 : 코드 블록({…})내에서 유효한 스코프를 의미한다.
    • “유효하다”라는 것은 “참조(접근)할 수 있다” 라는 뜻이다.

      int main(void) {
      	// block-level scope
      	if (1) {
      		int x = 5;
      		printf("x = %d\n", x);
      	}
      	
      	printf("x = %d\n", x); // use od undeclared identifier 'x'
      	
      	return 0;
      }

      위의 c언어 코드에서는 if문 내에서 선언된 변수 x는 if문 코드 블록 내부 내에서만 유효하다. if문 코드 블록 밖에서는 참조가 불가능하다.

      하지만 자바스크립트는 함수 레벨 스코프를 따른다.

    • 함수 레벨 스코프 : 함수 코드 블록 내에서 선언된 변수는 함수 코드 블록 내에서만 유효하고 함수 외부에서는 유효하지 않다는 것. 단 ECMAScript 6에서 도입된 let 키워드를 사용하면 블록 레벨 스코프를 사용할 수 있다.

      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); // 0

전역 스코프

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

var global = 'global';

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

console.log(global);
console.log(local); // Uncaught ReferenceError: local is not defined

변수 global는 함수 영역 밖의 전역에서 선언되었다. 자바스크립트는 타 언어와는 달리 특별한 시작점이 없어서 위 코드와 같이 전역에 변수나 함수를 선언하기 쉽다.

c언어의 경우 main 함수가 시작점이 되기 때문에 대부분은 코드 main함수 내에 포함된다. c언어의 경우 전역 변수를 선언하기 위해서는 의도적으로 main 함수 밖에 변수를 선언하여야 한다.

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

비 블록 레벨 스코프

if (true) {
	var x = 5;
}
console.log(x);

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

함수 레벨 스코프

var a = 10; // 전역 변수

(function () {
	var b = 20; // 지역 변수
})();

console.log(a);// 10
console.log(b); // 'b' is not defined

자바스크립트는 함수 레벨 스코프를 사용한다. 즉, 함수 내에서 선언된 매개변수와 변수는 함수 외부에서는 유효하지 않다. 따라서 변수 b는 지역 변수이다.

렉시컬 스코프

  • 렉시컬 스코프 : 함수를 어디서 호출하는지가 아니라 어디에 선언하였는지에 따라 결정된다.
    • 자바스크립트는 렉시컬 스코프를 따르므로 함수를 선언한 시점에 상위 스코프가 결정된다. 함수를 어디에서 호출하였는지는 스코프 결정에 아무런 의미를 주지 않음. 예제 bar는 전역에 선언되었다. 따라서 함수 bar의 상위 스코프는 전역 스코프이고 위 예제는 전역 변수 x의 값 1을 두 번 출력한다.
      var x = 1;
      
      function foo() {
      	var x = 10;
      	bar();
      }
      
      function bar() {
      	 console.log(x);
      }
      
      foo(); 
      bar();
      함수 bar의 상위 스코프가 무엇인지에 따라 결정된다. 두 가지 패턴을 예측 가능.
      1. 함수를 어디서 호출하였는지에 따라 상위 스코프를 결정
        1. → 함수의 상위 스코프를 결정하면 함수 bar의 상위 스코프는 함수 foo와 전역
      2. 함수를 어디서 선언하였는지에 따라 상위 스코프를 결정
        1. → 함수 스코프를 결정하면 함수 bar의 스코프는 전역이다
profile
개발공부일기

0개의 댓글