Function scope / Block scope
Javascript 에서는 function scope 와 block 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 메소드를 수행했기 때문에 존재하지 않는다.
'JavaScript' 카테고리의 다른 글
JS) Function (0) | 2025.03.30 |
---|---|
[JavaScript 공부용] Webworker 다뤄보기 (1) | 2024.11.20 |
Hugo 로 Github 페이지 블로그 만들기 (0) | 2023.08.16 |
ES6 이후 함수들 (0) | 2021.09.25 |