댓글 검색 목록

[javascript] 자바 스크립트의 어려운 부분 마스터하기 : 클로저 I

페이지 정보

작성자 운영자 작성일 20-09-05 12:42 조회 611 댓글 0

클로저는 믿을 수 없을 만큼 간단하지만 이해하기에는 JavaScript의 매우 강력한 부분입니다. 콜백 함수가 강력한 이유, 비동기 JS와 그것이 포함하는 모든 것 (Promises 등)이 가능한 이유는 클로저입니다.


https://dev.to/ryanameri/mastering-hard-parts-of-javascript-closure-i-kg2


하지만 클로저는 무엇입니까? Dan Abramov가 가장 잘 설명합니다.


함수가 외부에서 정의 된 변수에 액세스 할 때 클로저가 있습니다.


예를 들어 이 코드 스니펫에는 클로저가 포함되어 있습니다. 


let users = ["Alice", "Dan", "Jessica"];
let query = "A";
let user = users.filter((user) => user.startsWith(query));


user => user.startsWith (query) 자체가 어떻게 함수인지 주목하십시오. 쿼리 변수를 사용합니다. 그러나 쿼리 변수는 해당 함수 외부에서 정의됩니다. 그것은 closure입니다. 


이것이 어떻게 가능한지? 다른 함수 내부에서 함수를 반환 할 때 함수 뿐만 아니라 "가변 환경"도 반환하기 때문입니다. 이 변수 환경에는 외부 함수에서 선언 된 모든 변수 또는 개체가 포함됩니다. 반환 된 함수는 이 외부 변수 환경에 대한 링크를 유지합니다. 이 링크는 공식적으로 '가변 환경'(C.O.V.E.)보다 Closure라고 합니다. 또는 영구 어휘 범위 참조 데이터 (P.L.S.R.D.).


개념이 약간 혼란스러울 수 있지만 이러한 연습을 함께 진행하여 마스터 할 것입니다. 항상 그렇듯이 내 솔루션을 보기 전에 먼저 문제를 해결 한 다음 비교하고 대조하는 것이 좋습니다.


연습 1 


함수를 만들고 반환하는 함수 createFunction을 만듭니다. 생성 된 함수가 호출되면 "hello"를 출력해야 합니다. createFunction을 완료했다고 생각되면 코드에서 해당 줄의 주석 처리를 제거하고 실행하여 작동하는지 확인하십시오. 


function createFunction() {}
const function1 = createFunction();
function1();
// => should console.log('hello');



해결책 1 


function createFunction() {
  function printHello() {
    console.log("hello");
  }
  return printHello;
}


멋지고 쉬운 시작이지만 이것은 완벽한 마무리 데모입니다. 먼저 createFunction()을 호출하고 그 값을 function1에 할당합니다. function1은 이제 실제로 반환 된 것과 같이 printHello () 함수입니다. 이제 function1 ()을 호출 할 수 있으며 printHello() 함수의 본문을 실행합니다.


연습 2 


하나의 입력을 받아들이고 함수를 반환하는 함수 createFunctionPrinter를 만듭니다. 생성 된 함수가 호출되면 함수 생성시 사용 된 입력을 출력해야 합니다. 


function createFunctionPrinter() {}
const printSample = createFunctionPrinter("sample");
printSample();
// => should console.log('sample');
const printHello = createFunctionPrinter("hello");
printHello();
// => should console.log('hello');



해결 방법 2


function createFunctionPrinter(input) {
  function printInput() {
    console.log(input);
  }
  return printInput;
}


이전 연습과 매우 유사하지만 여기에서 COVE 또는 P.L.S.R.D의 개념도 시연하고 있습니다. 내부 함수 printInput()은 외부 함수,이 인스턴스에서는 매개 변수 입력에 있던 변수에 액세스합니다.


연습 3 


외부 함수에 대한 코드를 조사하십시오. 함수를 반환하고 함수가 범위를 벗어난 변수를 사용하고 있음에 유의하십시오.

실행하기 전에 출력을 추론하십시오. 


function outer() {
  let counter = 0;
  // this variable is outside incrementCounter's scope
  function incrementCounter() {
    counter++;
    console.log("counter", counter);
  }
  return incrementCounter;
}

const willCounter = outer();
const jasCounter = outer();
willCounter();
willCounter();
willCounter();

jasCounter();
willCounter();


이제 x로 입력을 추가하는 함수를 반환하는 함수 addByX를 만듭니다.


function addByX() {}
const addByTwo = addByX(2);
console.log(addByTwo(1));
// => should return 3
console.log(addByTwo(2));
// => should return 4
console.log(addByTwo(3));
// => should return 5

const addByThree = addByX(3);
console.log(addByThree(1));
// => should return 4
console.log(addByThree(2));
// => should return 5

const addByFour = addByX(4);
console.log(addByFour(4));
// => should return 8
console.log(addByFour(5));
// => should return 9



해결책 3 


function addByX(x) {
  function addByNum(num) {
    return num + x;
  }
  return addByNum;
}


우리는 이러한 유형의 기능을 이해해야 합니다. addByX가 처음 호출되면 인수를 받고 함수를 반환합니다. 이 내부 함수는 자체적으로 매개 변수를 수신하지만 자체 매개 변수와 addByX 매개 변수 모두에 액세스하므로 둘 다에 필요한 모든 계산을 수행 할 수 있습니다.


연습 4 


콜백을 입력으로 받아들이고 함수를 반환하는 함수를 한 번 작성합니다. 반환 된 함수가 처음 호출 될 때 콜백을 호출하고 해당 출력을 반환해야 합니다. 추가로 호출되는 경우 콜백을 다시 호출하는 대신 처음 호출 된 출력 값을 반환합니다. 


function once() {}

// /*** Uncomment these to check your work! ***/
const onceFunc = once(addByTwo);
console.log(onceFunc(4)); // => should log 6
console.log(onceFunc(10)); // => should log 6
console.log(onceFunc(9001)); // => should log 6


해결 방법 4 


function once(func) {
  let counter = 0;
  let res = undefined;
  function runOnce(num) {
    if (counter === 0) {
      res = func(num);
      counter++;
    }

    return res;
  }
  return runOnce;
}



이것은 클로저를 사용하여 함수에 메모리를 제공하는 방법을 볼 수 있는 첫 번째 예제입니다. 외부 범위에서 카운터 변수를 선언 한 다음 내부 함수에서 변경하면 함수가 몇 번 호출되었는지 확인한 다음 내부 함수가 호출 된 횟수에 따라 다른 동작을 수행 할 수 있습니다. 이것은 우리의 기능에 훨씬 더 많은 유연성과 힘을 제공하며, 다음 연습에서 더 자세히 살펴볼 것입니다.


연습 5 


그 후 첫 번째 매개 변수로 실행되고 두 번째 매개 변수로 콜백이 실행되기 전에 콜백을 호출해야 하는 횟수를 사용하여 함수를 작성합니다. 


function after() {}
const called = function () {
  console.log("hello");
};
const afterCalled = after(3, called);
afterCalled(); // => nothing is printed
afterCalled(); // => nothing is printed
afterCalled(); // => 'hello' is printed


해결책 5 


function after(count, func) {
  let counter = 0;
  function runAfter() {
    counter++;
    if (count === counter) {
      func();
    }
  }
  return runAfter;
}



이전 연습과 유사한 예로서 여기서는 다른 동작을 보여주고 있습니다. 다시 우리는 함수가 호출 된 횟수를 결정할 수 있는 카운터를 외부 범위에 설정할 수 있음을 알 수 있습니다. 그리고 이를 바탕으로 우리는 기능에 대해 다른 로직을 구현할 수 있습니다.



댓글목록 0

등록된 댓글이 없습니다.

웹학교 로고

온라인 코딩학교

코리아뉴스 2001 - , All right reserved.