JS 스코프

gang_shik·2025년 3월 19일
0

JavaScript

목록 보기
13/23

전역 스코프 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) // undefined

  var hoist = '호이스팅'; // 호이스팅

  console.log(hoist); // 호이스팅
}

foo() // undefined
  • 위와 같이 주석처럼 값이 나옴, 그래도 오류가 나지 않음, 이는 호이스팅 때문임
  • JS는 변수 선언을 직접적으로 끌어올림, 그래서 위의 실행 결과가 오류가 나지 않는 것임
  • 그래서 위의 예시에서 실제 실행결과는 아래와 같이 되는 것임
function foo() {
  // 선언이 끌어올려지는 것
  var hoist
  console.log(hoist);

  hoist = '호이스팅';

  console.log(hoist);
}

foo()
  • 이를 방지하기 위해서 let, const만 써도 충분함, 그러면 이를 암시적 사각 지대(TDZ)라고 해서 호이스팅은 일어나지만 이에 대해서 오류를 통해서 방지를 함
function foo() {
  console.log(hoist)

  let hoist = '호이스팅'; // const hoist = '호이스팅';

  console.log(hoist);
}

foo()
  • 선언과 실행했을 때 이러한 호이스팅의 동작 방식이 다름

IIFE(Immediately Invoked Function Expression)

  • 즉시 실행 함수 표현을 IIFE라고 함, 정의되자마자 즉시 실행되는 것임(마치 연산자에서 괄호가 먼저 실행되듯이)
  • 함수를 괄호 안에 두고 바로 실행시키는 것
(function() {})();
  • 이를 쓰는 이유는 공간을 완전히 분리할 수 있기 때문임, 함수가 있다면 명확하게 새로운 스코프를 만들 수 있기 때문임
  • 아래와 같이 즉시 실행 함수를 통해 스코프가 명확하게 되어 있기에 그 안에서만 쓰고 처리할 수 있게 됨, 일종의 블록 스코프를 흉내낸 것
  • 즉, 즉시 실행 함수구나라고 생각하기보다 일종의 블록 스코프를 흉내내는 새로운 스코프를 만들어내는구나 생각하면 좋음
if (true) {
  (function() {
    var temp = 'hello';

    console.log(temp);
  })()
}

// temp 사용불가
console.log(temp);

(function() { // IIFE 시작
  // IIFE 내부 동작 코드
})() // IIFE 종료
  • 단 이 즉시 실행함수는 세미콜론을 앞에 붙이든 뒤에 붙이든 확실하게 붙여야 구분할 수 있음, 그래야 영역을 구분하고 여러개를 처리할 수 있음
;(function() {})()
(function() {})();
  • 매개변수는 아래와 같이 쓸 수 있음
(function(num) {
  console.log(num);
})(1) // 1을 인자로 받아 매개변수 num으로 처리
  • 지금은 많이 사용하지 않긴함, let, const를 사용한다면 스코프나 호이스팅의 문제가 없으니
  • 하지만 아래와 같이 공간적으로 숨겨진 데이터나 변수를 내부적으로만 두려고 할 때 활용할 수 있음
  • 클로저 사용 방식이 즉시 실행 함수와 비슷함(React Hook과 동작원리도 비슷함)
(function(num) {
  var privateData = 'secret'
})(1)
profile
측정할 수 없으면 관리할 수 없고, 관리할 수 없으면 개선시킬 수도 없다

0개의 댓글