면접에서 Javascript 과제에 즉시 실행 함수를 사용한 것을 보고 전역 공간 오염을 막기 위해서 그렇게 코드를 짰는지 질문을 받았었다.
당시에 전역 공간 사용을 최소화하려는 의도도 아니었고, 전역 공간 사용을 안해야 한다는 것도 몰랐기 때문에 공부를 더 해봐야겠다고 생각했다.
전역공간은 최상위 스코프다.
왜 전역 공간 사용을 줄여야할까?
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<script src="index.js"></script>
</body>
</html>
// index.js
var globalVar = "global";
console.log(window);
이렇게 전역 변수를 선언하고 html
을 만들어서 javascript
를 브라우저에서 실행시키면 window
객체를 확인할 수 있다.
아주 많은 값들 중에 이상한 게 하나 껴있다.
전역 변수로 선언했던 값이다.
이처럼 전역 변수를 만들면 window
객체 안에 변수가 만들어지고 window.globalVar
로 접근도 가능하다.
window
객체에서 전역 변수에 접근할 수 있다는 것이 큰 문제가 될 수 있다.
index2.js
라는 다른 파일을 하나 더 만들고 window.globalVar
에 접근해보자.
<!DOCTYPE html>
<html lang="en">
...
<body>
<script src="index.js"></script>
<script src="index2.js"></script>
</body>
</html>
// index2.js
console.log("index2", window.globalVar);
이처럼 파일을 나눠도 전역공간에 선언한 변수를 참조할 수 있다.
즉, 스코프가 나뉘지 않는다.
이 말은 파일이 여러 개가 되면 변수를 중복 선언하게 될 수도 있다는 뜻이다.
전역 변수는 window 객체 안에 만들어진다는 것을 위에서 보았다.
그러면 window 객체 안에 있는 global method와 같은 이름으로 선언하면 어떻게 될까?
var setTimeout = "global";
console.log(window);
setTimeout
변수를 선언해보니 메서드가 없어지고 "global"
로 할당되어 있는 것을 볼 수 있다.
이처럼 전역 변수를 잘못 사용하면 메서드를 사용할 수 없게 된다.
전역에서는 IIFE(즉시실행함수) 사용하기
-> 전역 공간에 함수가 선언되는 것을 방지한다.
Module 사용하기
-> 모듈 파일에서 함수 밖에 선언된 변수는 전역 스코프가 아닌 모듈 스코프에 등록된다.
var
대신 const
, let
사용하기
->var
는 block scope가 아니라서 for문 등에 사용하면 전역 공간을 오염시킬 수 있다.
closure 사용하기