>  기사  >  웹 프론트엔드  >  JavaScript 클로저에 대한 간략한 소개

JavaScript 클로저에 대한 간략한 소개

WBOY
WBOY앞으로
2023-01-21 06:30:021106검색

이 기사는 JavaScript 클로저와 관련된 문제를 주로 소개하는 JavaScript 관련 지식을 제공합니다. 클로저 개념에는 여러 버전이 있으며, 클로저에 대한 의견도 다릅니다. 함께 살펴보겠습니다. 모든 사람.

JavaScript 클로저에 대한 간략한 소개

폐쇄란 무엇인가요?

클로저 개념에는 다양한 버전이 있으며, 장소마다 클로저에 대한 의견이 다릅니다

Wikipedia: 컴퓨터 과학에서 어휘 클로저 또는 함수 클로저라고도 알려진 클로저(영어: Closure)는 어휘 바인딩을 구현하는 기술입니다. 일류 기능을 지원하는 프로그래밍 언어.

MDN: 클로저는 함수와 번들로 묶인 주변 환경(어휘 환경, 어휘 환경)에 대한 참조의 조합입니다.

개인적인 이해:

    클로저는 함수입니다(함수를 반환함)
  • 반환된 함수는 외부 변수 참조를 저장합니다.
간단한 예

function fn() {    let num = 1;    return function (n) {        return n + num
    }
}let rFn = fn()let newN = rFn(3) // 4

num 변수 범위는 fn 함수, rFn 함수에 있지만 이는 num 변수에 액세스할 수 있다는 의미입니다. 이는 클로저 함수가 외부 함수 변수에 액세스할 수 있음을 의미합니다.

브라우저 디버깅 및 VSCode Nodejs 디버깅에서 클로저를 살펴보세요

    Browser

JavaScript 클로저에 대한 간략한 소개

    VS Code with Node.js

JavaScript 클로저에 대한 간략한 소개

클로저의 fn은 num 변수를 저장하는 클로저 함수입니다.

클래식 클로저: 단일 스레드 이벤트 메커니즘 + 루프 문제 및 솔루션

for (var i = 1; i  {    console.log(i);
  }, i * 1000);
}

출력 결과가 모두 6인데, 왜일까요?

    for 루프는 동기 작업입니다.
  • setTimeout 비동기 작업
for 루프는 한 번만 실행하면 setTimeout 비동기 작업이 브라우저의 비동기 작업 대기열에 추가됩니다. 동기 작업이 완료된 후 새 작업이 브라우저의 비동기 작업 대기열에 추가됩니다. 비동기 작업이 스레드에서 실행됩니다. setTimeout은 외부 변수 i에 접근할 수 있으므로 동기화 작업이 완료되면 i는 6이 되고, setTimeout에서 접근할 수 있는 변수 i는 모두 6이 된다.

해결책 1: let 문 사용

for (var i = 1; i  {    console.log(i);
  }, i * 1000);
}

해결책 2: 자체 실행 기능 + 클로저

for (var i = 1; i  {    console.log(i);
  }, i * 1000)
  })(i)
}

해결책 3: setTimeout이 세 번째 매개변수를 전달합니다

세 번째 매개변수의 의미: 추가 매개변수, 타이머가 도착하면 기간, 실행될 함수에 매개변수로 전달됩니다

for (var i = 1; i  {    console.log(j);
  }, 1000 * i, i);
}
클로저 및 함수 curry

function add(num) {  return function (y) {    return num + y;
  };
};let incOneFn = add(1); let n = incOneFn(1);  // 2let decOneFn = add(-1); let m = decOneFn(1); // 0

add 함수의 매개변수는 클로저 함수 변수를 저장합니다.

실제 효과参数保存了闭包函数变量。

实际作用

在函数式编程闭包有非常重要的作用,lodash 等早期工具函数弥补 javascript 缺陷的工具函数,有大量的闭包的使用场景。

使用场景

  • 创建私有变量
  • 延长变量生命周期

节流函数

防止滚动行为,过度执行函数,必须要节流, 节流函数接受 函数 + 时间作为参数,都是闭包中变量,以下是一个简单 setTimeout 版本:

function throttle(fn, time=300){    var t = null;    return function(){        if(t) return;
        t = setTimeout(() => {
            fn.call(this);
            t = null;
        }, time);
    }
}

防抖函数

一个简单的基于 setTimeout 防抖的函数的实现

function debounce(fn,wait){    var timer = null;    return function(){        if(timer !== null){            clearTimeout(timer);
        }
        timer = setTimeout(fn,wait);
    }
}

React.useCallback 闭包陷阱问题

问题说明:父/子 组件关系, 父子组件都能使用 click 事件同时修改 state 数据, 并且子组件拿到传递下的 props 事件属性,是经过 useCallback

클로저는 함수형 프로그래밍에서 매우 중요한 역할을 합니다. Lodash 및 JavaScript의 단점을 보완하는 기타 초기 도구 기능에는 클로저에 대한 사용 시나리오가 많이 있습니다. .

  • 사용 시나리오
개인 변수 생성

변수 수명 주기 연장

제한 기능

스크롤 동작과 함수의 과도한 실행을 방지하려면 조절이 필요합니다. 조절 기능은 클로저의 변수인 function + time을 매개변수로 허용합니다. 다음은 간단한 setTimeout입니다. 버전 :🎜
import { useState, useCallback, memo } from "react";const ChildWithMemo = memo((props: any) => {  return (    <div>
      <button>Child click</button>
    </div>
  );
});const Parent = () => {  const [count, setCount] = useState(1);  const handleClickWithUseCallback = useCallback(() => {    console.log(count);
  }, []); // 注意这里是不能监听 count, 因为每次变化都会重新绑定,造成造成子组件重新渲染

  return (    <div>
      <div>parent count : {count}</div>
      <button> setCount(count + 1)}>click</button>
      <childwithmemo></childwithmemo>
    </div>
  );
};export default Parent

🎜손떨림 방지 기능🎜🎜🎜setTimeout을 기반으로 한 손떨림 방지 기능의 간단한 구현🎜
import { useState, useCallback, memo, useRef } from "react";const ChildWithMemo = memo((props: any) => {  console.log("rendered children")  return (    <div>
      <button> props.countRef.current()}>Child click</button>
    </div>
  );
});const Parent = () => {  const [count, setCount] = useState(1);  const countRef = useRef<any>(null)

  countRef.current = () => {    console.log(count);
  }  return (    <div>
      <div>parent count : {count}</div>
      <button> setCount(count + 1)}>click</button>
      <childwithmemo></childwithmemo>
    </div>
  );
};export default Parent</any>

React .useCallback 클로저 트랩 문제🎜🎜문제 설명: 상위/하위 구성 요소 관계, 상위 및 하위 구성 요소는 click 이벤트를 사용하여 동시에 상태 데이터를 수정할 수 있으며 하위 구성 요소는 전달된 props 이벤트를 가져옵니다. useCallback을 통해 속성이 최적화되었습니다. 즉, 이 최적화된 함수에는 클로저 트랩이 있습니다. (초기 상태 값은 항상 저장됩니다.) 🎜rrreee🎜🎜ChildWithMemo는 최적화를 위해 메모를 사용하고, 🎜🎜handleClickWithUseCallback은 최적화를 위해 useCallback을 사용합니다🎜🎜🎜🎜문제는 하위 구성 요소가 클릭하면 출력 개수는 초기값(닫힘)입니다. 🎜🎜🎜해결책은 useRef를 사용하여 운영 변수 함수를 저장하는 것입니다. 🎜rrreee🎜이 문제에 대해 React는 한때 커뮤니티의 useEvent 추가 제안을 승인했지만 나중에 useEvent 의미 문제는 렌더링 최적화를 위해 포기되었습니다. 컴파일 최적화 솔루션. 실제로 useEffect에서도 비슷한 문제가 발생합니다. 사용할 때 클로저 트랩에 주의하세요. 🎜

성능 문제

  • 클로저를 임의로 정의하지 마세요. 정의한 후에는 파기에 적합한 위치를 찾아야 합니다. 클로저의 변수는 메모리에 저장되고 소멸되지 않기 때문에 많은 양의 메모리를 차지합니다.

크롬 패널 기능 타임라인 + 프로필 패널 사용

  1. 개발자 도구를 열고 타임라인 패널 선택
  2. 상단 Capture 필드에서 메모리 확인
  3. 왼쪽 상단에 있는 녹화 버튼을 클릭하세요.
  4. 페이지에서 다양한 작업을 수행하여 사용자 사용을 시뮬레이션합니다.
  5. 일정 시간이 지난 후 대화 상자에서 중지 버튼을 클릭하면 이 기간 동안의 메모리 사용량이 패널에 표시됩니다.

【관련 추천: JavaScript 비디오 튜토리얼, 웹 프론트엔드

위 내용은 JavaScript 클로저에 대한 간략한 소개의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 juejin.im에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제