Javascript 개념 - 스코프

pa324·2019년 11월 14일
0

스코프(Scope) 정의

  • scope를 한글로 해석하면 범위 라는 뜻을 가지고 있다.
  • javascript상에서 scope는 변수,함수가 가지는 범위를 의미한다.
  • 스코프는 변수,상수,매개변수가 언제 어디서 정의되는지를 결정한다.
function a(x) {
  return x + 5;
}
a(5) // 10
x; // x is no defined

x의 스코프는 함수 a

스코프(Scope) Level

함수 레벨 스코프

  • 자바스크립트는 기본적으로 "함수 레벨 스코프"를 지원
  • var키워드로 선언된 변수, 함수선언식 으로 만들어진 함수는 함수 레벨 스코프를 가진다.
function b () {
	if(true) {
    	var test = 'test';
    }
  	console.log(test);
  	
}

함수 레벨 스코프를 가지기 때문에, test가 정상적으로 출력된다.

블록 레벨 스코프

  • es6부터 제공된 'let', 'const' 키워드는 "블록 레벨 스코프"를 지원
function b () {
	if(true) {
    	let test = 'test';
    }
  	console.log(test);
  	
}

블록 레벨 스코프를 가지기 때문에, console.log를 할때 test는 존재하지 않는다.

전역 스코프

  • Global Scope는 스코프의 최상위에 있다.
  • 프로그램을 시작할 때 암시적으로 주어지는 스코프가 필요한데, 이 스코프를 전역 스코프라고 한다(window object)
  • 전역 스코프를 사용하는 것을 피해야 한다.
    • 서로 다른 곳에서 전역스코프를 의존하면 여러가지 문제가 발생할 수 있다,
let hello = "hello"
let age = "26"
function hello () {
	console.log(`${hello} ${age}`);
}

위와 같은 전역스코프는 지양해야 한다.

Lexical Scope, Dynamic Scope

자바스크립트는 Lexical Scope를 지원한다. 그렇다면 Lexical Scope와 Dynamic Scope는 뭘까? Lexical Scope는 정적 스코프라고 정의할 수 있고, Dynamic Scope는 동적 스코프라고 정의할 수 있다.
Lexical Scope규칙을 따르는 자바스크립트의 함수는 호출 스택과 관계없이 각각의 대응표를 소스코드 기준으로 정의하고, 런타임에 그 대응표를 변경시키지 않는다.

var x = 'global';

function foo () {

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

Lexical Scope를 따르는 자바스크립트는 아래와 같은 형태로 출력된다.

global
global

만약, Dynamic Scope를 따른다면 아래와 같이 출력되었을 것이다.

local
global
  • Lexical Scope (정적 스코프)
    • 소스코드가 작성된 context에서 결정
  • Dynamic Scope (동적 스코프)
    • 프로그램 런타임 도중의 실행 context나 호출 context에 의해 결정

const x = 4;
function test() {
	console.log(x); // o
  	console.log(y); // x
}
{
	const y = 5;
  	test();
}

자바스크립트는 정적 스코프이다. 위의 예제를 보면 함수 test는 선언 당시의 스코프를 참조해서 x는 출력할 수 있지만, y는 test선언 당시 스코프에 존재하지 않기때문에 error가 발생한다.

스코프 체인

스코프 체인이란, 새롭게 정의된 스코프는 상위 스코프에 접근할 수 있는 성질을 의미한다. Lexical Environment 대응표에서 변수를 찾아보고, 없다면 상위 렉시컬 환경을 참조하여 찾아보는 식으로 중첩 스코프가 가능해 진다. 중첩 스코프 탐색은 해당하는 변수를 찾거나 상위 렉시컬 환경 참조가 null이 될 때 탐색을 멈춘다.

//global scope
function a {
	// new block scope
}

Temporal dead zone

"let으로 선언한 변수는 선언하기 전까지 존재하지 않는다"

profile
안녕하세요

0개의 댓글