[SEB_FE_45] 2023.04.26 / 클로저

Kay·2023년 4월 26일
0

📖 [강의 내용 및 개념 정리]
목차

시작 전에 추천하는 아티클

medium - 자바스크립트는 왜 프로토타입을 선택했을까

이 글에서 저자는 자바스크립트의 "프로토타입 기반의 객체지향", "렉시컬스코프", "this", "스코프"와 같은 개념에 대해 한 논문을 참고하여 이야기를 풀어 설명해주십니다!

(*제 부족한 실력으로 논문을 요약하자면 다음과 같습니다.)

  • "클래스 기반의 객체지향 모델"과 "프로토타입 기반의 객체지향 모델"은 기원이 되는 학자의 이론이 다르다.
  • 그로 인해 각 모델의 특징과 언어적 특징이 다르다.

프로토타입 기반의 객체지향 모델이 지닌 특징 중 렉시컬 스코프(Lexical Scope)란 무엇일까?

Rosch의 프로토타입 이론의 내용 중

"현실에 존재하는 것 중 가장 좋은 본보기가 원형(Prototyoe)이며, 문맥(Context)에 따라 범주, 즉 의미가 달라진다."

라는 내용이 있으며, 렉시컬 스코프(Lexical Scope)의 개념과 일맥상통한다.

MDN의 정의는

"함수와 함수가 선언된 어휘적(lexical) 환경의 조합을 말한다. 이 환경은 클로저가 생성된 시점의 유효 범위 내에 있는 모든 지역 변수로 구성된다."

이다.

즉, 함수가 호출되는 환경과 별개로 기존에 선언되어 있던 환경, 즉 어휘적 환경을 기준으로 변수를 조회한다는 것이다.

클로저 기초

클로저(closure)란?

MDN은 클로저(closure)를 다음과 같이 정의한다.

A closure is the combination of a function bundled together (enclosed) with references to its surrounding state (the lexical environment). - mdn (2023)

즉, 클로저는 함수와 그 함수 주변의 상태의 주소 조합이다.
쉽게 풀어 쓰면, "클로저는 함수와 그 함수가 접근할 수 있는 변수의 조합"이라는 의미이다.

const globalVar = '전역 변수';

function outerFn() {
  const outerFnVar = 'outer 함수 내의 변수';
  const innerFn = function() { 
    return 'innerFn은 ' + outerFnVar + '와 ' + globalVar + '에 접근할 수 있습니다.';
  }
	return innerFn;
}

위 코드에서의 클로저 조합

  • 함수 outerFn과 outerFn에서 접근할 수 있는 globalVar
  • 함수 innerFn과 innerFn에서 접근할 수 있는 globalVar, outerFnVar

클로저 함수: 외부 함수의 변수에 접근할 수 있는 내부 함수
클로저의 함수는 어디에서 호출되느냐와 무관하게 선언된 함수 주변 환경에 따라 접근할 수 있는 변수가 정해진다.

클로저 활용

데이터를 보존하는 함수

function createFoodRecipe (foodName) {
  const getFoodRecipe = function (ingredient1, ingredient2) {
    return `${ingredient1} + ${ingredient2} = ${foodName}!`;
  }
  return getFoodRecipe;
}

const highballRecipe = createFoodRecipe('하이볼');
highballRecipe('콜라', '위스키'); // '콜라 + 위스키 = 하이볼!'
highballRecipe('탄산수', '위스키'); // '탄산수 + 위스키 = 하이볼!'
highballRecipe('토닉워터', '연태고량주'); // '토닉워터 + 연태고량주 = 하이볼!'

highballRecipe 함수는 문자열 ‘하이볼’을 보존하고 있어서 전달인자를 추가로 전달할 필요가 없고, 다양한 하이볼 레시피를 하나의 함수로 제작할 수 있다.

커링

여러 전달인자를 가진 함수를 연속적으로 리턴하는 함수

function makePancake(powder) {
  return function (sugar) {
		return function (pan) {
			return `팬케이크 완성! 재료: ${powder}, ${sugar} 조리도구: ${pan}`;
		}
	}
}

const addSugar = makePancake('팬케이크가루');
const cookPancake = addSugar('백설탕');
const morningPancake = cookPancake('후라이팬');

// 팬케이크 완성! 재료: 팬케이크가루, 백설탕, 조리도구: 후라이팬
console.log(morningPancake);

const lunchPancake = cookPancake('냄비');
// 팬케이크 완성! 재료: 팬케이크가루, 백설탕, 조리도구: 냄비
console.log(lunchPancake);

중요!) 이와 같이 커링은 함수의 일부만 호출하거나, 일부 프로세스가 완료된 상태를 저장하기에 용이함

하지만, 커링으로 작성되지 않은 일반 함수는 모든 파라미터를 전달해야 하며, 일부를 생략하여 작성할 수 없다.

function makePancakeAtOnce (powder, sugar, pan) {
  return `팬케이크 완성! 재료: ${powder}, ${sugar} 조리도구: ${pan}`;
}

const morningPancake = makePancakeAtOnce('팬케이크가루', '흑설탕', '후라이팬')

// 팬케이크 완성! 재료: 팬케이크가루, 흑설탕, 조리도구: 후라이팬
console.log(morningPancake);

모듈 패턴

모듈: 하나의 기능을 온전히 수행하기 위한 모든 코드를 가지고 있는 코드 모음으로, 하나의 단위로서 역할
중요!!!) 모듈은 다른 모듈에 의존적이지 않고 독립적이어야 함

function makeCalculator() {
  let displayValue = 0;

  return {
    add: function(num) {
      displayValue = displayValue + num;
    },
    subtract: function(num) {
      displayValue = displayValue - num;
    },
    multiply: function(num) {
      displayValue = displayValue * num;
    },
    divide: function(num) {
      displayValue = displayValue / num;
    },
    reset: function() {
      displayValue = 0;
    },
    display: function() {
      return displayValue
    }
  }
}

const cal = makeCalculator();
cal.display(); // 0
cal.add(1);
cal.display(); // 1
console.log(displayValue) // ReferenceError: displayValue is not defined

displayValue는 makeCalculator의 코드 블록 외에 다른 곳에서는 접근이 불가능하지만,
cal의 메서드는 모두 클로저의 함수로서 displayValue에 접근할 수 있다.

이렇게 데이터를 다른 코드 실행으로부터 보호하는 개념을 정보 은닉(information hiding)이라고 하며, 이는 캡슐화(encapsulation)의 큰 특징이다.

중요!!!) 클로저는 특정 데이터를 다른 코드의 실행으로부터 보호해야 할 때 용이

끝나면서 추천하는 아티클

medium - 자바스크립트 클로저로 Hooks구현하기
github 개인 블로그 - Vanilla Javascript로 React UseState Hook 만들기
velog - React Hooks - vanilla JavaScript로 구현하기

위 세개의 글에서 저자들은 자바스크립트 클로저 개념를 활용하여 React의 hook 기능을 바닐라 자바스크립트로 구현하는 과정을 설명해 주십니다!

위 아티클들을 참고하여 CustomReact 를 만들고 이 세팅 위에 개인 프로젝트를 진행하고 있다.

개인적으로 이러한 과정을 통해 자바스크립트의 기본 문법, 동작 원리들, 클로저와 같은 개념에 대해 궁금증을 가지고 공부하는 좋은 영향을 받아 추천하게 되었다.

간단하게라도 개인 프로젝트에 이 클로저 개념을 활용한 hook을 넣어보시면 어떠신지! 추천드리며 이번 포스팅은 마무리!!!

0개의 댓글