분류 Nodejs

JavaScript 클로저가 필요한 이유에 대한 간단한 예

컨텐츠 정보

  • 조회 473 (작성일 )

본문

결국 JavaScript Closure라는 개념을 보게 될 것입니다. JavaScript Closure를 구현하는 방법을 단계별로 안내하고 싶습니다. 

그 과정에서 JavaScript Closures로 특정 것을 구현하는 것이 왜 합리적인지 스스로 알게 될 것입니다. 전체 소스 코드는 GitHub에서 찾을 수 있습니다. 코드를 작성하려면 먼저 JavaScript 프로젝트를 설정하십시오.


왜 자바 스크립트 클로저인가? 


우리에게 객체를 반환하는 다음 JavaScript 함수가 있다고 가정 해 봅시다. 객체의 속성은 들어오는 함수의 인수를 기반으로 합니다.


function getEmployee(name, country) {
  return { name, country };
}

const employeeOne = getEmployee('Robin', 'Germany');
const employeeTwo = getEmployee('Markus', 'Canada');

const employees = [employeeOne, employeeTwo];


이 경우 함수는 직원 개체에 대한 개체를 만듭니다. 이 함수를 사용하여 여러 객체를 하나씩 만들 수 있습니다. 나중에 이러한 객체로 무엇을 하고 있는지는 귀하에게 달려 있습니다. 예를 들어, 회사 직원 목록을 얻기 위해 배열에 배치하십시오.


직원을 구별하기 위해 직원 번호 (식별자)를 제공해야 합니다. 함수를 호출 할 때 외부에서 번호를 신경 쓰고 싶지 않기 때문에 식별자는 내부적으로 할당해야 합니다.


https://www.robinwieruch.de/javascript-closure/ 


function getEmployee(name, country) {
  let employeeNumber = 1;
  return { employeeNumber, name, country };
}

const employeeOne = getEmployee('Robin', 'Germany');
const employeeTwo = getEmployee('Markus', 'Canada');

const employees = [employeeOne, employeeTwo];

console.log(employees);

// [
//   { employeeNumber: 1, name: 'Robin', country: 'Germany' },
//   { employeeNumber: 1, name: 'Markus', country: 'Canada' },
// ]

현재 모든 직원의 직원 번호는 1 명이며 올바르지 않습니다. 고유 식별자 여야 합니다. 일반적으로 직원 수는 회사의 모든 직원에게 1 씩 증가합니다. 그러나 외부에서 무언가를 할 수 없으면 이 기능은 이미 작성된 직원 수를 알지 못합니다. 상태를 추적하지 않습니다.


함수는 내부 상태를 유지하지 않으므로 변수를 함수 외부로 이동하여 생성 된 모든 직원과 함께 함수 내에서 변수를 증가 시켜야 합니다. 함수가 호출 될 때마다 숫자를 증가 시켜 상태를 추적합니다.


let employeeNumber = 1;

function getEmployee(name, country) {
  return { employeeNumber: employeeNumber++, name, country };
}

const employeeOne = getEmployee('Robin', 'Germany');
const employeeTwo = getEmployee('Markus', 'Canada');

const employees = [employeeOne, employeeTwo];

console.log(employees);

// [
//   { employeeNumber: 1, name: 'Robin', country: 'Germany' },
//   { employeeNumber: 2, name: 'Markus', country: 'Canada' },
// ]



참고 : ++ 연산자 (증분 연산자)는 정수를 1 씩 증가 시킵니다. postfix (예 : myInteger ++)를 사용하면 정수가 증가하지만 증가하기 전에 값을 반환합니다. 접두사 (예 : ++ myInteger)를 사용하면 정수를 증가 시키고 증가 시킨 후에 값을 반환합니다. 반대로 JavaScript에는 Decrement Operator도 있습니다.


이 기능을 구현하기 위한 한 가지 중요한 단계가 있습니다. 상태를 추적하기 위해 변수를 함수 범위 밖으로 옮겼습니다. 함수에 의해 내부적으로 관리되기 전에 함수만이 변수에 대해 알고 있었습니다. 이제 우리는 그것을 외부로 옮기고 전 세계적으로 사용할 수 있게 했습니다.


이제 변수의 새로운 전역 범위로 문제를 해결할 수 있습니다.


let employeeNumber = 1;

function getEmployee(name, country) {
  return { employeeNumber: employeeNumber++, name, country };
}

const employeeOne = getEmployee('Robin', 'Germany');
employeeNumber = 50;
const employeeTwo = getEmployee('Markus', 'Canada');

const employees = [employeeOne, employeeTwo];

console.log(employees);

// [
//   { employeeNumber: 1, name: 'Robin', country: 'Germany' },
//   { employeeNumber: 50, name: 'Markus', country: 'Canada' },
// ]



직원 번호가 기능의 범위에 숨겨져 있었기 때문에 가능하지 않았습니다. 변수의 범위 지정으로 인해 기능의 외부 컨텍스트에 액세스 할 수 없었습니다. 우리의 기능이 작동하더라도 이전 코드 스니펫은 잠재적 인 함정이 있음을 분명히 보여줍니다.


이전 코드 스니펫에서 수행 한 모든 것은 변수 범위를 함수 범위에서 전역 범위로 변경하는 것이었습니다. JavaScript Closure는 변수 범위의 문제를 해결하여 함수 외부에서는 액세스 할 수 없지만 함수는 내부 상태를 추적 할 수 있습니다. 기본적으로 프로그래밍에 스코프가 있으면 숨쉬는 공기가 막힙니다.


예제 별 JavaScript 클로저 


JavaScript 클로저는 변수 범위의 문제를 해결합니다. 클로저를 사용하면 이 변수의 로컬 범위를 포기하지 않고도 함수에서 변수로 내부 상태를 추적 할 수 있습니다.


function getEmployeeFactory() {
  let employeeNumber = 1;
  return function(name, country) {
    return { employeeNumber: employeeNumber++, name, country };
  };
}

const getEmployee = getEmployeeFactory();

const employeeOne = getEmployee('Robin', 'Germany');
const employeeTwo = getEmployee('Markus', 'Canada');

const employees = [employeeOne, employeeTwo];

console.log(employees);

// [
//   { employeeNumber: 1, name: 'Robin', country: 'Germany' },
//   { employeeNumber: 2, name: 'Markus', country: 'Canada' },
// ]


새로운 함수는 처음 호출 할 때 함수를 반환하기 때문에 고차 함수가 되었습니다. 이 반환 함수는 이전과 마찬가지로 직원을 만드는 데 사용할 수 있습니다. 그러나 주변 함수는 리턴 된 함수 주위에 상태 저장 환경 (이 경우 상태 저장 직원 번호)을 작성하므로 이를 closure라고 합니다.


“클로저는 독립 (자유) 변수를 나타내는 함수입니다. 다시 말해 클로저에 정의 된 함수는 생성 된 환경을 '기억'합니다.”(출처 : MDN 웹 문서) 


외부에서는 더 이상 직원 번호를 엉망으로 만들 수 없습니다. 그것은 전 세계적 범위가 아니라 우리 함수의 종결에 있습니다. 이름을 지정할 수 있는 getEmployee 함수를 작성하면 직원 번호가 내부적으로 상태로 유지됩니다.


참고 :이 예제에 대한 이전의 JavaScript Closure 구현은 소프트웨어 개발에서 "공장 패턴"이라고도 합니다. 기본적으로 외부 함수는 공장 함수이며 이 함수는 이 공장 사양에서 "항목"(여기서는 직원)을 생성하는 함수입니다. 


이 간단한 연습이 예제로 JavaScript 클로저를 이해하는 데 도움이 되었기를 바랍니다. 변수 범위 지정과 함수의 내부 상태를 추적하는 문제부터 시작하여 클로저를 구현하여 문제를 해결했습니다.