[TIL] JS - 스코프와 클로저

Alex J. Lee·2021년 9월 8일
0

TIL

목록 보기
13/58

Today I Learned

스코프 (Scope)

스코프란?

  • 변수의 유효범위
  • 자바스크립트는 렉시컬 스코프(lexical scope)를 따르기 때문에 해당 변수가 어디에서 선언되었는지에 따라 스코프가 결정된다.
  • 내부 스코프에서 외부 스코프의 변수에 접근할 수는 있지만, 외부 스코프에서 내부 스코프의 변수에는 접근할 수 없다.

전역 스코프 (Global Scope)

  • 가장 외부에 있는 스코프
  • 전역 스코프에 있는 전역 변수는 어디에서든 참조할 수 있다.
  • 전역 스코프의 문제점 : namespace 충돌이나 의도하지 않은 override가 발생할 수 있음

지역 스코프 (Local Scope)

  • 함수나 블록(중괄호({ })로 감싸진 구역)으로 만들어진 스코프
  • 함수의 매개변수는 해당 함수 스코프의 지역 변수로 취급된다.
  • 지역 스코프 내의 지역 변수는 해당 스코프의 외부에서 참조할 수 없다.

함수 스코프 (Function Scope)

  • 함수의 매개변수와 함수 내부에서 선언된 함수는 외부에서 참조할 수 없다.

블록 스코프 (Block Scope)

  • 블록(중괄호({ })로 감싸진 구역)으로 만들어진 스코프
  • if, switch, for, while은 각각 블록 스코프를 형성한다.

var, let and const

  • ES6 이전에 쓰였던 var 키워드는 함수 스코프를 따르며 블록 스코프는 무시한다.

  • letconst는 블록 스코프를 인지한다.

  • var가 아닌 let, const를 사용해야 하는 이유 : var는 재선언되어 오류를 발생시킬 여지가 있다. 또한 let, const는 블록 스코프를 가지므로 함수 스코프를 가지는 var보다 예측 가능하다.

  • // LET -----
    for (let i = 0; i < 3; i++) {
      console.log('current : ' + i);
    }
    console.log('last : ' + i);
    // current : 0
    // current : 1
    // current : 2
    // last : undefined (let으로 선언된 i는 for loop 밖에서 접근 불가)
    // VAR -----
    for (var j = 0; j < 3; j++) {
      console.log('current : ' + j);
    }
    console.log('last : ' + j);
    // current : 0
    // current : 1
    // current : 2
    // last : 3 (var로 선언된 j는 블록 스코프를 따르지 않기 때문에 for loop 밖에서도 접근 가능)

스코프 체인 (Scope Chain)

  • 스코프는 중첩 가능하며 가장 인접한 스코프부터 순차적으로 참조한다.

클로저 (Closure)

클로저란?

  • 함수와 함수가 선언된 어휘적 환경(lexcial environmnet)의 조합 (MDN)
  • 함수형 프로그래밍 언어의 주요 특징 중 하나이다.
  • 중첩된 함수에서 내부 함수는 자신이 속한 lexical scope(즉, 외부 함수의 스코프)를 참조할 수 있다. 외부 함수가 실행이 끝나고 실행 컨텍스트 스택에서 제거된 후에도 내부 함수는 여전히 외부 함수 안에 존재하는 변수들에 접근할 수 있다. 클로저를 많이 쓸 경우 실행이 끝난 외부 함수의 변수들을 계속 저장하고 있기 때문에 메모리를 많이 사용하게 된다.

클로저가 유용한 상황

  • 현재 상태를 기억해야 하는 경우
  • 전역 변수대신 지역 변수를 사용하도록 하여 side effect를 줄임
  • 정보 은닉
function makeCounter() {
  let count = 0;
  return {
    increase: () => {
      count++;
    },
    getCount: () => count,
  };
}

const counter = makeCounter();
counter.increase(); // (count의 값을 1 증가 시킴)
console.log(counter.getCount()); // 1 (count의 값을 리턴함)
console.log(count); // ReferenceError

// 변수 count는 makeCounter 함수 외부에서 접근할 수 없지만
// increase와 getCount 함수는 자신들의 lexical environment에 속한 변수 count에 접근할 수 있다.
profile
🦄✨글 잘 쓰는 개발자가 되기 위해 꾸준히 기록합니다 ✨🦄

0개의 댓글