Home Modern Javascript Deepdive [ Chapter 14 스코프 ]
Post
Cancel

Modern Javascript Deepdive [ Chapter 14 스코프 ]

DesktopView

이 게시물은 SW마에스트로 연수생 간 진행한 Modern JavaScript DeepDive 스터디 개인 정리 내용입니다.
되도록 책의 내용을 그대로 적기보단 개인적으로 인상깊었던 부분을 구어체로 풀어쓰려 노력했습니다.

Modern JavaScript Deep Dive

Chapter _ 14 전역 변수의 문제점

전역 변수의 무분별한 사용은 위험합니다. 또한 전역 변수를 사용해야하는 명확한 이유가 없다면 지역변수를 사용하는것이 옳습니다.

이런 말이 나온 이유는 왜 그런 것인지, 그리고 어떻게 회피할 수 있을 지 알아보도록 하겠습니다.

변수의 생명주기

변수는 선언에 의해 생성되고 할당을 통해 값을 갖습니다. 하지만 이에 더해 변수는 생명 주기를 갖습니다. 생성되고 일정 시간이 지나면 소멸하게 됩니다.

만약 이러한 생명주기를 갖지 않는다면 모든 변수들은 프로그램이 종료될 때 까지 메모리 공간을 점유하게 됩니다.

물론 몇몇 변수들은 실제로 프로그램 실행과 함께 생성되고, 프로그램이 종료되며 그 생명 주기가 끝날 것입니다. 하지만 중요한 부분은 모든 변수가 그렇다면 메모리 관리에 심각한 문제가 발생할 수 있다는 점 입니다.

하지만 다행히도 JavaScript의 변수들은 생명주기를 가지고 있습니다.

실제로 활용되고 있는 JS 지역변수의 간단한 예시를 보도록 하겠습니다.

1
2
3
4
5
6
7
function foo() {
	var x = 'local'
	console.log(x) // local
	return x
}
foo()
console.log(x) // RefError !! 

위 예제와 같이 함수 내부에서 선언된 지역변수는 함수의 생명주기와 일치하여 함수가 호출되어 실행되는 도중에만 유효합니다.

즉, 스코프 내부에서 선언된 변수들은 함수과 끝나는 것과 동시에 메모리 할당이 해제되고 해당 메모리는 가용 메모리 풀로 반환됩니다.

전역 변수의 생명 주기

함수와 다르게 전역 코드는 별도의 명시적 호출 없이 실행됩니다. 즉, 앞선 함수 예제와 다르게 특별한 함수 호출 없이 코드가 들어오자마자 실행되게 되고, 또 앞선 함수 예제와 다르게 반환값을 사용할 수 없기 때문에 마지막 문이 실행되며 더이상 실행할 수 있는 문이 없을때. 즉, 프로그램이 종료될 때 종료됩니다.

여기서 var 키워드는 전역변수로 선언된다고 우리는 알고 있습니다. 이 var 키워드 전역변수는 전역객체의 프로퍼티가 됩니다.

브라우저의 경우 전역 객체는 window 이므로, var 로 선언한 전역 변수는 window 의 프로퍼티가 되어 브라우저 환경에서는 웹 페이지를 닫을 때 까지 유효한 변수가 됩니다.

전역 변수의 문제점

앞서서 간단하게 메모리 관리에서 문제점이 발생할 수 있으며, 현재 var 키워드로 선언된 변수들은 전역변수로 할당된다는 사실을 알 수 있었습니다.

그렇다면 이번엔 전역변수의 문제점에 대해 조금 더 자세히 알아보도록 하겠습니다.

암묵적 결합

전역코드는 코드 어디서든 참조하고 할당할 수 있는 변수입니다. 즉, 어디서든 참조하고 변경되는 암묵적 결합을 허용하는 것입니다.

암묵적 결합은 코드가 방대해 질수록 의도치 않은 변화를 야기할 수 있는 유지보수, 개발 관점에서 위험한 개념입니다.

긴 생명주기

앞서 말했던 메모리 관리에서의 문제점입니다. 사실 암묵적 결합의 경우엔 정말 신경을 잘 쓸 수 있는 휴먼에러 0의 팀이라면 문제를 일으키지 않을 수 있습니다.

하지만 긴 생명주기를 가지는 문제는 의도적으로 할당을 초기화하지 않는다면 메모리 자원을 지속적으로 낭비하게 됩니다.

스코프 체인의 종점에 존재

전역 변수는 모든 스코프를 체크하고 나서 마지막에 체크하는 전역 스코프에 위치합니다. 즉, 변수 검색속도 또한 가장 느린 것을 의미합니다.

사실 변수 검색은 큰 시간을 소요하지 않지만, 그래도 비교적 느리다는것은 확실합니다.

네임스페이스 오염

변수를 짓는 것은 어려운 작업 중 하나입니다. 만약 전역 변수를 사용하게 된다면, 한 번 사용한 변수는 다시 사용하지 못한다는 것을 의미합니다.

전역 변수 사용을 억제하기

처음 시작하며 전역 변수 사용의 명확한 이유가 없으면 사용하지 않는게 옳다는 말을 했습니다. 이 말인 즉, 명확한 이유가 있으면 사용해도 좋습니다. 하지만 그렇지 않은 경우 회피하는 방법을 알고 있어야 할 것입니다.

즉시 실행 함수

모든 코드를 즉시 실행 함수로 감싸면 변수는 즉시 실행 함수의 지역변수로 취급됩니다.

변수는 함수와 생명주기를 같이한다고 했던 앞부분이 기억 나시나요?

그 특징을 역으로 이용한 것이라고 이해하면 좋을 듯 합니다.

네임스페이스 객체

전역에 아예 네임스페이스 역할을 담당할 객체를 생성하고 전역변수처럼 사용하고 싶은 변수를 프로퍼티로 추가하는 방법.

네임스페이스에 넣는 방식으로 식별자 충돌을 회피할 수 있지만, 여전히 전역객체이기 때문에 저자는 추천하지 않는다고 한다.

모듈 패턴

클래스를 모방해 관련 있는 변수와 함수를 모아 즉시 실행 함수로 감싸 하나의 모듈을 만드는 방법입니다.

모듈 패턴은 JS의 강력한 기능 중 하나인 클로저를 기반으로 동작하며, 전역변수의 억제는 물론이고 캡슐화까지 구현할 수 있다는 점입니다.

ES6 모듈

실제로 JS 를 접하며 저희는( 적어도 저는 ) 옛날 자료를 기반으로 공부해보더라도 var 키워드가 전역변수로 작동한다는 느낌을 받을 수 없었습니다.

그 이유는 ES6 모듈을 사용하면 더 이상 전역 변수를 사용할 수 없기 때문입니다. ES6 모듈은 파일 자체의 독자적 모듈스코프를 제공하기 때문에 더이상 var 키워드는 전역변수가 아니며, window 객체의 프로퍼티도 아닙니다.

실제로 ES6 는 2015 년에 릴리즈 되었기 때문에 제가 웹개발을 본격적으로 접할 땐 이미 ES6 문법이 자리를 잡고 난 이후였기 때문입니다.

This post is licensed under CC BY 4.0 by the author.