전역 스코프 vs 지역 스코프
- 함수 스코프 & 블록 스코프는 지역 스코프라고 볼 수 있음
- 전역 스코프는 Global이라고 하는데, 가장 바깥쪽에 있는 부분임, 어디서든 접근이 가능하나 그만큼 어디서든 수정도 가능함을 의미함(값이 똑같을 거라는 보장이 없음)
- 이로 인해서 예측하기가 상당히 어려워짐, 프로그램이 실행되는 시점(런타임) 전까진 어떻게 되는지 알 수가 없음
- 스코프가 있는 것이 일종의 안전지대라고도 볼 수 있음(정해져 있기 떄문에 바운더리가)
let foo = 'foo'
{
foo = 'fooooooo'
console.log(foo);
}
function func() {
foo = 'foooo'
console.log(foo);
}
if (true) {
foo = 'foooooooooo'
console.log(foo);
}
- 그래서 지역 스코프 단위로 연습하는 습관을 들이는게 좋음 즉, 막연하게 전역 스코프로 쉽게 쉽게 하는 방법을 지양하라
전역 객체
- 브라우저에서는 window객체가 전역 객체임 굉장히 많은 DOM이나 다양한 이벤트, 함수등이 있음
- 콘솔에서
this
로 호출 시 전역객체인 window를 호출할 수 있음, 이 때 맘대로 값을 넣을 수도 있음
window.foo = 'foo';
- 전역 객체이기에 어느 스코프 등 어디서든 값을 집어넣고 접근할 수가 있음
- 여기서 전역 객체는 2가지로 나뉘어짐
- 브라우저 환경인 window 객체와 서버 환경 NodeJS에서의 global 객체임
- 이러한 전역 객체를 편리하게 사용하지만 마음대로 값을 넣고 처리하는 것은 주의해야함
호이스팅
function foo() {
console.log(hoist)
var hoist = '호이스팅';
console.log(hoist);
}
foo()
- 위와 같이 주석처럼 값이 나옴, 그래도 오류가 나지 않음, 이는 호이스팅 때문임
- JS는 변수 선언을 직접적으로 끌어올림, 그래서 위의 실행 결과가 오류가 나지 않는 것임
- 그래서 위의 예시에서 실제 실행결과는 아래와 같이 되는 것임
function foo() {
var hoist
console.log(hoist);
hoist = '호이스팅';
console.log(hoist);
}
foo()
- 이를 방지하기 위해서
let
, const
만 써도 충분함, 그러면 이를 암시적 사각 지대(TDZ)라고 해서 호이스팅은 일어나지만 이에 대해서 오류를 통해서 방지를 함
function foo() {
console.log(hoist)
let hoist = '호이스팅';
console.log(hoist);
}
foo()
- 선언과 실행했을 때 이러한 호이스팅의 동작 방식이 다름
- 즉시 실행 함수 표현을 IIFE라고 함, 정의되자마자 즉시 실행되는 것임(마치 연산자에서 괄호가 먼저 실행되듯이)
- 함수를 괄호 안에 두고 바로 실행시키는 것
(function() {})();
- 이를 쓰는 이유는 공간을 완전히 분리할 수 있기 때문임, 함수가 있다면 명확하게 새로운 스코프를 만들 수 있기 때문임
- 아래와 같이 즉시 실행 함수를 통해 스코프가 명확하게 되어 있기에 그 안에서만 쓰고 처리할 수 있게 됨, 일종의 블록 스코프를 흉내낸 것
- 즉, 즉시 실행 함수구나라고 생각하기보다 일종의 블록 스코프를 흉내내는 새로운 스코프를 만들어내는구나 생각하면 좋음
if (true) {
(function() {
var temp = 'hello';
console.log(temp);
})()
}
console.log(temp);
(function() {
})()
- 단 이 즉시 실행함수는 세미콜론을 앞에 붙이든 뒤에 붙이든 확실하게 붙여야 구분할 수 있음, 그래야 영역을 구분하고 여러개를 처리할 수 있음
;(function() {})()
(function() {})();
(function(num) {
console.log(num);
})(1)
- 지금은 많이 사용하지 않긴함, let, const를 사용한다면 스코프나 호이스팅의 문제가 없으니
- 하지만 아래와 같이 공간적으로 숨겨진 데이터나 변수를 내부적으로만 두려고 할 때 활용할 수 있음
- 클로저 사용 방식이 즉시 실행 함수와 비슷함(React Hook과 동작원리도 비슷함)
(function(num) {
var privateData = 'secret'
})(1)