JavaScript

JS) Function scope / Block scope

dev_roach 2025. 3. 30. 17:00
728x90

Function scope / Block scope

Javascript 에서는 function scopeblock scope 가 있다. 이점이 살짝 다른 언어만 해오던 나에게는 익숙해지지 않았는데, 바로 아래와 같은 이유 때문이다.

Function scope

var adult = true; if (adult) { ​​​​var myName = "Kyle"; ​​​​let age = 39; ​​​​console.log("Secret!"); } console.log(myName); // Kyle console.log(age); // ReferenceError: age is not defined

 

위의 코드를 보면 if 블럭안에 var myName 을 선언하고 “Kyle” 이라는 값을 할당했음에도 if 블록의 바깥 영역에서 myName 에 접근이 가능하다. 그 이유는 var 이 function scope 를 따르기 때문이다.

 

function scope 는 쉽게말해 함수 안에서 유효한 값을 가지게 되는데 현재 위 코드에서는 함수가 아닌 if block 안에 들어있으므로 호이스팅에 의해 더 상위인 전역 스코프로 선언부가 올라가게 된다. 할당하는 부분은 그대로 이고 선언부만 올라가게 된다.

<!DOCTYPE html> <html> <head> ​​​​<title>Scope Test</title> </head> <body> ​​​​<h1>Testing var Scope</h1> ​​​​<script> ​​​​​​​​console.log("Script start"); ​​​​​​​​var adult = true; ​​​​​​​​console.log("Before if:", typeof myName, myName); ​​​​​​​​if (adult) { ​​​​​​​​​​​​console.log("Inside if, before var:", typeof myName, myName); ​​​​​​​​​​​​var myName = "Kyle"; ​​​​​​​​​​​​let age = 39; ​​​​​​​​​​​​console.log("Inside if, after var:", myName, age); ​​​​​​​​​​​​console.log("Secret!"); ​​​​​​​​} ​​​​​​​​console.log("After if:", myName); ​​​​​​​​console.log("Script end"); // 종료점 확인용 ​​​​</script> </body> </html>

엔진이 이렇게 실제로 동작하는지 확인해보기 위해서는 브라우저의 디버거를 이용해보면 된다. 위 코드를 브라우저에 입력해보자.

실제로 브라우저에서 디버깅을 해보면 myName 이 이미 undefined 처리되어 있음을 알수 있다. 즉, 선언부가 호이스팅되어 글로벌하게 선언됬음을 알수 있다. 그렇다면 function scope 안에 있을때 밖에서 참조하려 할때 에러가 나는지 확인해보자.

function test() { ​​​​var myName = "Kyle"; } console.log(myName); // ReferenceError: myName is not defined

위와 같이 function scope 에 있을때는 외부에서 참조하려고 할시 에러가 잘 발생함을 확인할 수 있다. 이제 function scope 의 개념을 알았으니 Block scope 로 넘어가보자. 

 

P.S) var 의 function scope 의 개념이 다른 언어와 혼동을 줄수 있다고 해서 요즘에는 let 과 const 를 이용하라고 권장하는것 같은데 사실 개념만 알고 있다면 크게 문제는 없지 않을까 싶긴하다. 

Block scope

let, const 와 같은 선언문들은 block scope 를 가진다. 우리가 첫번째 예시에서도 봤듯이 let 과 const 로 선언된 변수는 동일 block 내에서만 참조 가능하다. 둘의 차이점이 있다면 const 는 불변(immutable) 하다. 아래의 코드를 함께 보자.

const myBirthday = true; let age = 39; if (myBirthday) { ​​​​age += 1; ​​​​myBirthday = false; // TypeError: Assignment to constant variable. }

코드를 실행시키면 위와 같이 myBirthday 를 false 로 할당시키려는 부분에서 에러가 발생한다. 이 이유는 const 로 할당한 값을 바꾸려고 했기 때문이다. const 로 된 값을 이용할때 우리는 일반적으로 처음 할당된 이후로 잘 바뀌지 않을 것이라고 예상한다. 그렇기 때문에 아래와 같이 객체를 할당해서 사용하면 유지보수 관점에서 문제를 일으킬수 있다.

const actors = ["Kyle", "Sarah", "Dr. Evil"]; actors.pop(); assert(actors.includes("Dr. Evil"));

 

위의 코드를 보면 알수 있듯이 const 로 선언했음에도 객체를 할당했기 때문에 객체의 값을 바꾸는 것이 가능하다. 따라서 사용하는 쪽에서 Dr. Evil 이 배열 객체안에 있을거라고 생각하지만, 실제로는 pop 메소드를 수행했기 때문에 존재하지 않는다. 



728x90

'JavaScript' 카테고리의 다른 글

JS) Function  (0) 2025.03.30
[JavaScript 공부용] Webworker 다뤄보기  (1) 2024.11.20
Hugo 로 Github 페이지 블로그 만들기  (0) 2023.08.16
ES6 이후 함수들  (0) 2021.09.25