[Javscript] 함수 스코프 vs 블록 스코프

2020. 9. 29. 13:34Frontend

 

https://scotch.io/tutorials/understanding-scope-in-javascript

 

 

 

스코프는 자바스크립트 이외에도 대부분의 프로그래밍 언어들이 가지고 있는 것으로, 변수나 함수가 선언되어 사용할 수 있는 유효 범위에 대해 정의합니다. 이번 포스팅에서는 자바스크립트에서의 함수 스코프(function scope)와, ES6 표준에서 새롭게 추가된 let, const 키워드가 제공하는 블록 스코프(block scope)에 대해서 살펴보려고 합니다.

 

 

 

함수 스코프 (+ 전역 스코프)

 

자바스크립트는 기본적으로 전역 스코프(Global Scope)와 함수 스코프(Function Scope)를 가집니다. 앞서 언급한 것처럼 스코프는 변수나 함수가 선언되어 사용할 수 있는 유효 범위를 정의하기 때문에 전역 스코프인지, 함수 스코프인지에 따라서 변수가 사용될 수 있는 범위가 달라집니다. 아래의 예시를 보겠습니다.

 

 

기본적으로 자바스크립트에서는 함수 바깥에 선언된 모든 변수들에 대해서 전역 스코프를 부여합니다. 이 전역 스코프는 코드 내의 어디에서든지 접근할 수 있으며, 전역 객체인 window의 프로퍼티로 들어가게 됩니다. 

 

 

 

 

또한 암묵적 전역(Implicit Global) 원칙에 따라 다음과 같이 선언하지 않는 변수를 사용할 때도, 참조 에러를 발생시키는 것이 아니라 암묵적으로 전역 객체인 window에 등록되게 됩니다. (여기서 window가 전역 객체인 이유는 현재 브라우저 콘솔에서 테스트하는 것이므로 자바스크립트 런타임이 브라우저이기 때문입니다. 런타임이 브라우저일 경우 전역 객체는 window, 런타임이 Node.js일 경우 전역 객체는 Global입니다.)

 

 

 

하지만 다음과 같이 함수 안에서 선언된 변수는 함수 스코프(function scope)를 가지게 됩니다. 따라서 함수 안에서 선언된 변수는 지역 변수(local variable)의 성격을 띠게 되며, 함수 외부에서 그 변수에 접근할 경우 참조 에러가 발생합니다.

 

 

var yeoul = 'coding';

(function () {
  var yeoul2 = 'writing';
}())

console.log(yeoul)
console.log(yeoul2);

 

 

함수 스코프와 전역 스코프에 동일한 변수가 선언되어 있을때는 실행 컨텍스트가 생성되는 과정에 의해 내부 스코프부터 참조하게 됩니다. 따라서 함수 내부에서 사용하려고 하는 변수가 함수 안에 선언되어 있으면 전역 스코프에 그 변수가 또 선언되어 있더라도 함수 안의 변수를 우선적으로 참조하게 됩니다. 

 

var yeoul = "coding";

function foo() {
  var yeoul = "writing";
  console.log(yeoul);
}

foo();

 

 

 

이렇게 "함수 내부에서 선언된 변수는 함수 내부에서만 유효하다"라는 성질이 함수 스코프의 핵심입니다. 이를 이용해서 클로저, 커링등의 패턴들을 구현할 수 있습니다. 

 

 

 

블록 스코프

 

블록 스코프는 원래 C와 같은 원시 언어에는 존재했지만 자바스크립트에서는 존재하지 않던 개념이었습니다. 하지만 ES6표준에서 let, const 키워드를 도입하면서 자바스크립트에서도 블록 스코프를 표현할 수 있게 됩니다.

 

블록 스코프란 블록 단위 (if-else문, while문, for문, try-catch문) 내에서만 유효 범위를 갖게 하는 스코프를 의미합니다. 앞서 언급한 블록단위 안에서 let이나 const 키워드로 선언한 변수는 블록 바깥에서 접근할 수 없다는 것이 핵심입니다. 

 

 

var을 통해서 변수를 선언하게 되면 전역 스코프와 함수 스코프만을 사용하겠다는 의미이므로 해당 블록 안에서 변수를 선언하여도 전역 스코프로 취급됩니다. 따라서 다음 예시에서는 정상적으로 'coding'이라는 값이 출력됩니다.

 

{
  var yeoul = 'coding';
}

console.log(yeoul);

 

 

 

let을 통해 변수를 선언하게 되면 해당 변수는 블록 스코프를 가지므로 해당 블록 내에서만 접근할 수 있어서 다음 코드는 참조 에러를 발생하게 됩니다. 

{
  let yeoul = "coding";
}

console.log(yeoul);

 

 

 

 

 

 

Reference

poiemaweb.com/js-scope

 

Scope | PoiemaWeb

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

poiemaweb.com

developer.mozilla.org/ko/docs/Glossary/%EC%8A%A4%EC%BD%94%ED%94%84

 

스코프

현재 실행되는 컨텍스트를 말한다. 여기서 컨텍스트는  값과 표현식이 "표현"되거나 참조 될 수 있음을 의미한다. 만약 변수 또는 다른 표현식이 "해당 스코프"내에 있지 않다면 사용할 수 없��

developer.mozilla.org

yeoulcoding.tistory.com/154

 

[Javascript] 호이스팅이란

Interview Section은 FrontEnd Interview Question에 대한 QnA를 다룹니다. Q. Explain "Hoisting" A. 호이스팅을 간단하게 정의하자면, 자바스크립트가 코드를 컴파일하는 과정에서 코드 내의 선언문들을 찾아..

yeoulcoding.tistory.com

 

반응형

'Frontend' 카테고리의 다른 글

[Javascript] 프로토타입 상속이란?  (0) 2020.10.02
[Javascript] Attribute vs Property  (1) 2020.09.29
[Javascript] 클로저란?  (0) 2020.09.28
[Javascript] 호이스팅이란  (0) 2020.09.28
[Javascript] forEach vs map (Array.prototype)  (0) 2020.09.27