자바스크립트 스코프(Scope)

hoo00nn·2020년 12월 29일
0
post-thumbnail
post-custom-banner

스코프(Scope)란 ?

작성된 코드를 둘러싼 환경으로, 변수에 접근할 수 있는 범위를 말한다.

전역 스코프와 지역 스코프

자바스크립트 스코프에는 두 가지 종류가 있다.

바로 전역 스코프지역 스코프 이다.

전역 스코프

전역 스코프는 변수가 함수 밖이나 {} 밖에서 선언되었다면, 전역 스코프에 정의 된다.

아래와 같이 전역 스코프에 변수를 선언한다면 모든 곳에서 선언한 변수에 접근할 수 있다. 심지어 함수안에서도 사용이 가능하다. 사용이 가능한 이유는 실행 컨텍스트와 실행 컨텍스트에 저장되어 있는 Scope 객체 때문에 가능한데, 이 내용은 스코프 체인 에 대해 정리할 때 설명하겠다.

const globalScope = 'scope'

function scopeChain () {
  console.log(globalScope)
}
console.log(globalScope) // 'scope'
scopeChain() // 'scope'

비록 위와같이 전역 스코프를 이용하여 변수를 선언할 수 있지만 그렇지 않는게 좋다.

왜냐하면, 두 개 이상의 변수의 이름이 충돌하는 경우가 생길 수도 있기 때문이다.

var 키워드를 사용하여 변수의 충돌을 없애고 변수의 값을 덮어씌울 수 있는데, 나중에 오류가 생겼을 때 디버깅을 어렵게 하기 때문에 좋은 방법이 아니다.

let dup = '변수 선언됨'
let dup = '중복됨' // dup라는 변수가 이미 선언되어 문제발생

var dup2 = 'var 키워드 사용하지 말자'
var dup2 = '왜?' // dup2 변수의 값이 'var 키워드 사용하지 말자' 에서 '왜?' 로 덮어 씌워진다.

지역 스코프

자바스크립트에는 크게 두 가지 지역 스코프가 존재한다.

바로 함수 스코프블록 스코프 이다.

함수 스코프

만약 함수 내부에서 변수를 선언한다면, 그 변수는 선언한 함수 내부에서만 사용이 가능하다.

또한, 스코프는 함수가 호출될 때가 아닌 함수가 선언될 때 정해진다. 이 부분은 Lexical Scope에서 중요하게 다뤄진다.

function funcScope () {
  const hello = 'Hello hoo00nn'
  console.log(hello)
}
funcScope() // 'Hello hoo00nn'
console.log(hello) // Error, hello is not defined

블록 스코프

블록 스코프는 여러분이 중괄호({}) 내부에서 const 또는 let 으로 변수를 선언하면, 그 변수들은 중괄호 블록 내부에서만 사용이 가능하다.

{
  const hello = 'Hello hoo00nn'
  console.log(hello) // 'Hello hoo00nn'
}
console.log(hello) // Error, hello is not defined

정적 범위(Lexical Scope)

렉시컬 스코프란, 함수를 어디서 호출하는지가 아니라 어떤 스코프에 선언하였는지에 따라 결정된다는 것이다.

아래의 코드를 설명하며 이해해보자.

var text = 'global';

function foo() {
	console.log(text);
}

function bar() {
	var text = 'bar';
	foo();
}

bar(); // 출력은 ? 

일반적으로 드는 생각은

  1. bar 함수 내부에서 text 변수가 "bar"로 선언되었고
  2. 함수 내부에서 foo 함수를 호출하면
  3. foo함수 내부에서 text를 찾을 수 없어
  4. 상위 스코프인 bar함수에서 text를 찾고 "bar"를 출력할 것 같지 않나요?

하지만 실행하면 "global"이 출력된다. 이유는 스코프는 함수가 호출될 때가 아닌 함수가 선언될 때 정해지기 때문이다

다시 말해 foo 함수가 선언될 때 스코프가 생성이 되고, text는 foo함수의 상위 스코프인 전역 스코프의 text를 참조하게 되기 때문이다.

결론은 "어디서 호출하는지가 아니라 처음 선언되었을 때에 어떤 스코프에 있는지" 가 중요하다.

만약 text를 bar로 바꾼 후에 출력하고 싶다면, 지역변수 var를 선언할 것이 아니라 전역변수 var의 값을 바꾸면 된다.

var text = 'global';

function foo() {
    console.log(text);
}

function bar() {
    text = 'bar';
    foo();
}

bar();

참고자료

profile
😀 신기술에 관심이 많고, 함께 성장하고 함께 개발하고 싶은 개발자가 되고 싶습니다. 😀
post-custom-banner

0개의 댓글