코어 자바스크립트 5장: 클로저

송나은·2021년 6월 8일
1

JavaScript

목록 보기
21/23

클로저

어떤 함수 A에서 선언한 변수 a를 참조하는 내부함수 B를 외부로 전달할 경우 A의 실행 컨텍스트가 종료된 이후에도 변수 a가 사라지지 않는 현상.

(=외부 함수의 LexicalEnvrionment가 가비지 컬렉팅되지 않는 현상.)

클로저에 대한 정의

  • 함수를 선언할 때 만들어지는 유효범위가 사라진 후에도 호출할 수 있는 함수
  • 이미 생명주기가 끝난 외부 함수의 변수를 참조하는 함수

메모리 소모

클로저는 그 본질이 메모리를 계속 차지하는 개념이므로 더는 사용하지 않게 된 클로저에 대해 메모리를 차지하지 않도록 관리해줄 필요가 있다.

필요성이 사라진 시점에 식별자에 기본형 데이터 null을 할당하여 참조 카운트를 0으로 만든다.

클로저 활용법 1) 콜백 함수 내부에서 외부 데이터를 사용하고자 할 때

  • 콜백함수를 내부함수로 선언해서 외부변수를 직접 참조한다.
  • bind 메서드로 값을 직접 넘겨준다. 클로저x
  • 콜백함수를 고차함수로 바꿔서 클로저를 적극 활용한다.

✍ 고차함수: 함수를 인자로 받거나 함수를 리턴하는 함수

const animals = ['cat', 'dog', 'fox'];
const $ul = document.createElement('ul');

// 고차함수
const alertAnimalBuilder = function (animal) {
  return function () {
    alert('your choice is ' + animal);
  };
};
animals.forEach(function (animal) {
  const $li = document.createElement('li');
  $li.innerText = animal;
  // addEventListenter는 콜백 함수를 호출할 때 첫 번째 인자에 '이벤트 객체'를 주입한다.
  $li.addEventListener('click', alertAnimalBuilder(animal));
  $li.appendChild($li);
});
document.body.appendChild($ul);

클로저 활용법 2) 접근 권한 제어(정보 은닉)

어떤 모듈의 내부 로직에 대해 외부로의 노출을 최소화해서 모듈간의 결합도를 낮추고 유연성을 높이고자 하는 것.

return을 활용해서 외부 스코프에서 함수 내부의 변수들 중 선택적으로 일부의 변수에 대한 접근 권한을 부여할 수 있다.

클로저 활용법 3) 부분적용함수

n개의 인자를 받는 함수에 미리 m개의 인자만 넘겨 기억시켰다가, 나중에 (n-m)개의 인자를 넘기면 비로소 원래 함수의 실행 결과를 얻을 수 있게 하는 함수

디바운스

짧은 시간 동안 동일한 이벤트가 많이 발생할 경우 이를 전부 처리하지 않고 처음 또는 마지막에 발생한 이벤트에 대해 한 번만 처리하는 것.

프론트엔드 성능 최적화에 도움.

Symbol.for 메서드

전역 심볼공간에 인자로 넘어온 문자열이 이미 있으면 해당 값을 참조하고, 선언돼 있지 않으면 새로 만드는 방식.

어디서는 접근 가능하면서 유일무이한 상수를 만들고자 할 때 적합하다.

클로저 활용법 4) 커링함수

여러 개의 인자를 받는 함수를 하나의 인자만 받는 함수로 나눠서 순차적으로 호출될 수 있게 체인 형태로 구성한 것.

  • 한 번에 하나의 인자만 전달한다.
  • 중간 과정상의 함수를 실행한 결과는 마지막 인자가 전달되기 전까지 원본 함수가 실행되지 않는다. (=지연실행)
const curry = func => a => b => c => d => e => func(a, b, c, d, e);

예) 원하는 시점까지 지연시켰다가 실행하는 것이 요긴한 상황
예) 자주 쓰이는 함수의 매개변수가 항상 비슷하고 일부만 바뀌는 경우

const getInfo = baseURL => path => id => fetch(baseUrl + path + '/' + id);
const URL = https://velog.io/@songbetter

const getVelog = getInfo(URL); // https://velog.io/@songbetter
const getSeries = getVelog('series') // https://velog.io/@songbetter/series
const series1 = getVelog('javascript') // https://velog.io/@songbetter/series/javascript
// Redux Middleware 'Logger'
const logger = store => next => action => {
  console.log('dispatching', action);
  console.log('next state', store.getState());
  return next(action);
};
// Redux Middleware 'thunk'
const thunk = store => next => action => {
  return typeof action === 'function'
    ? action(dispatch, store.getState)
    : next(action);
};

Reference

코어자바스크립트 / 정재남

profile
그때그때 공부한 내용과 생각을 기록하는 블로그입니다.

0개의 댓글