프론트엔드 개발이 꼭 알아야 할 JS 클로저와 애플리케이션_javascript 기술
프론트엔드 개발이 꼭 알아야 할 JS 프로토타입과 상속이라는 글에서 클로저에 대한 글을 쓰겠다고 언급한 적이 있습니다. 게다가 최근에 클로저 애플리케이션 역량을 강화해야 한다는 걸 알게 되었기 때문에 이 글은 더 이상 미룰 수 없습니다. 더 길게. 이 기사에서는 함수 클로저에 대해 설명하며 객체 클로저(예: with 사용)는 포함하지 않습니다. 제가 말한 내용이 틀렸다고 생각하시면 언제든지 댓글과 조언 부탁드립니다.
1. 폐쇄 이론
먼저 다음 개념을 이해해야 합니다.
실행 환경
함수가 호출될 때마다(함수가 호출될 때) 실행됨) 시스템은 함수의 실행 환경인 함수에 대한 폐쇄형 로컬 실행 환경을 생성합니다. 함수는 로컬 변수, 함수 매개변수 읽기 및 쓰기, 내부 논리 실행 등 항상 자체 실행 환경에서 실행됩니다. 실행 환경을 만드는 과정에는 함수의 범위를 만드는 과정이 포함되며, 함수도 자체 범위에서 실행됩니다. 다른 관점에서 보면 각 함수 실행 환경에는 범위 체인이 있고 하위 함수의 범위 체인에는 상위 함수의 범위 체인이 포함됩니다. 범위 및 범위 체인은 아래를 참조하세요.
스코프, 스코프 체인, 호출 객체
함수 범위는 어휘 범위와 동적 범위로 구분됩니다.
어휘 범위는 함수가 정의될 때의 범위, 즉 정적 범위입니다. 함수가 정의되면 어휘 범위가 결정됩니다. 어휘 범위는 함수 구조의 중첩 관계에 따라 함수의 범위를 설명합니다. 이때 함수의 범위 체인이 형성됩니다. 범위 체인은 이러한 범위를 중첩된 계층 관계로 연결하는 것입니다. 함수의 내부 [[scope]] 속성은 이 범위 체인을 가리킵니다.
동적 범위는 함수 호출이 실행될 때의 범위입니다. 함수가 호출되면 함수 내부의 [[scope]] 속성이 먼저 함수의 범위 체인을 가리킨 다음 호출 개체가 생성되고 호출 개체는 함수 매개 변수 및 지역 변수를 기록하는 데 사용됩니다. 함수를 도메인 체인의 최상위에 배치합니다. 이때, [[scope]]는 정의할 때 스코프 체인을 가질 뿐만 아니라, 호출할 때 호출 객체도 생성하게 됩니다. 즉, 실행 환경의 범위는 함수가 정의될 때 결정된 범위 체인과 함수에 의해 방금 생성된 호출 개체를 더해 새로운 범위 체인을 형성하는 것과 같습니다. 따라서 이는 동적 범위이고 범위 체인도 이에 따라 변경됩니다. 여기서 범위를 보면 실제로는 객체 체인입니다. 이러한 객체는 함수가 호출될 때 생성되는 호출 객체이며, 그 위에 있는 호출 객체는 최상위 전역 객체입니다.
예를 들어 전역 환경의 함수 A에 함수 B가 중첩되어 있는 경우 함수 B의 범위 체인은 함수 B의 범위 -> 함수 A의 범위 -> 전역 창의 범위입니다. . 함수 B가 호출되면 식별자를 찾을 때 함수 B의 범위 -> 함수 A의 범위 -> 전역 창의 범위에 따라 검색됩니다. 실제로는 호출에 따라 검색됩니다. 함수 B의 객체 -> 함수 A -> 전역 객체의 호출 객체를 이 순서대로 검색합니다. 즉, 함수가 호출될 때 함수의 범위 체인은 실제로 호출 개체 체인입니다.
클로저
동적 실행 환경에서는 데이터가 실시간으로 변경됩니다. 이러한 비영속적 변수의 값을 유지하기 위해 이러한 동적 데이터를 저장하는 캐리어로 클로저를 사용합니다(읽기). 다음 이 문장을 적용해 보면 아주 잘 이해될 것입니다. 클로저의 정의: 소위 "클로저"는 많은 변수와 이러한 변수에 바인딩된 환경이 있는 표현식(일반적으로 함수)을 의미하므로 이러한 변수도 표현식의 일부입니다.
클로저는 함수 안에 중첩된 내부 함수이며, 내부 함수는 외부 함수에 선언된 모든 지역 변수, 매개변수 및 기타 내부 함수에 액세스할 수 있습니다. 내부 함수가 외부 함수 외부에서 호출되면 클로저가 생성됩니다. (실제로 모든 함수는 전역 범위의 내부 함수이고 전역 변수에 접근할 수 있으므로 창을 닫는 것입니다)
예를 들어 다음 예는
가비지 수집 메커니즘: 객체가 더 이상 참조되지 않으면 객체가 재활용됩니다.
위에서 언급한 몇 가지 개념을 결합하면 var test=f(1)을 실행하면 f의 호출 객체가 생성됩니다. 여기서는 실행 후 외부 실행 환경이 종료되지만 내부 함수는 A 변수입니다. 외부 기능 외부의 테스트 참조 f. 외부 함수에 의해 생성된 호출 개체 obj에는 이 내부 함수를 가리키는 속성이 있고 이제 이 내부 함수가 참조되므로 호출 개체 obj는 계속 존재하며 해당 함수 매개 변수 x 및 가비지 수집기에 의해 재활용되지 않습니다. 지역 변수 a는 이 호출 개체에서 유지됩니다. 호출 객체에 직접 접근할 수는 없지만 호출 객체는 내부 함수 범위 체인의 일부가 되었고 내부 함수에 의해 접근 및 수정될 수 있으므로 test()가 실행될 때 x와 a에 올바르게 접근할 수 있습니다. 따라서 외부 함수가 실행되면 클로저가 생성되고, 참조되는 외부 함수의 변수는 계속 존재하게 됩니다.
2. 클로저 적용
적용 1:
이는 정렬 알고리즘을 시뮬레이션하기 위해 js를 사용하는 동안 발생한 문제입니다. 각 삽입 후에 정렬된 배열을 출력하고 싶습니다.
setTimeout(function() { $("proc").innerHTML = arr "
"; }, i * 500) ;
arr 배열은 각 정렬의 상태 값을 유지하지 않기 때문에 각 출력이 최종 정렬된 배열임을 알 수 있습니다. 끊임없이 변화하는 배열 값을 저장하기 위해 외부에 함수 레이어를 래핑하여 클로저를 구현하고 클로저를 사용하여 이 동적 데이터를 저장합니다. 아래의 클로저를 구현하는 데에는 두 가지 방법이 사용됩니다. 하나는 매개변수를 사용하여 배열의 값을 저장하는 것이고, 다른 하나는 임시 변수를 사용하여 값을 저장하는 것입니다. 클로저를 통해 저장해야 하는 모든 비영속 변수는 임시 변수 또는 매개변수라는 두 가지 방법으로 구현할 수 있습니다.
[Ctrl A 모두 선택 참고: 외부 J를 도입해야 하는 경우 실행하려면 새로 고쳐야 합니다.
애플리케이션 2:
이것은 클릭 이벤트 팝업 루프 인덱스 값을 각
id.onclick = function(){ Alert(i); } id.onclick = function(){alert(i);}
최종 팝업이 원하는 1이 아닌 4인 것을 발견했습니다. , 2, 3, 왜냐하면 루프가 완료된 후 i 값이 4가 되기 때문입니다. i의 값을 저장하기 위해 클로저도 사용합니다: 외부 J를 도입해야 하는 경우 실행하려면 새로 고쳐야 합니다.
]
( ps: var a = (function(){})(); var a =new function(){}과 동일한 효과를 가지며 둘 다 자체 실행 함수를 나타냅니다.)
애플리케이션 3:
同理,也可以用这种思想实现自增长的ID。
应用4:
这个是无忧上月MM的例子(点击这里查看原帖),用闭包实现程序的暂停执行功能,还蛮创意的。
[Ctrl+A 全选 注:如需引入外部Js需刷新才能执行]
把这个作用延伸下,我想到了用他来实现window.confirm。
[Ctrl+A 全选 注:如需引入外部Js需刷新才能执行]
看了上面的这些应用,再回到前面的一句话:在动态执行环境中,数据实时地发生变化,为了保持这些非持久型变量的值,我们用闭包这种载体来存储这些动态数据。这就是闭包的作用。也就说遇到需要存储动态变化的数据或将被回收的数据时,我们可以通过外面再包裹一层函数形成闭包来解决。
当然,闭包会导致很多外部函数的调用对象不能释放,滥用闭包会使得内存泄露,所以在频繁生成闭包的情景下我们要估计下他带来的副作用。
毕了。希望能对大家有所帮助。
者:JayChow
出处:http://ljchow.cnblogs.com

핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

AI Hentai Generator
AI Hentai를 무료로 생성하십시오.

인기 기사

뜨거운 도구

메모장++7.3.1
사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전
중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기
강력한 PHP 통합 개발 환경

드림위버 CS6
시각적 웹 개발 도구

SublimeText3 Mac 버전
신 수준의 코드 편집 소프트웨어(SublimeText3)

뜨거운 주제











홈 화면에서 중요한 항목을 삭제하고 다시 복구하려고 하시나요? 다양한 방법으로 앱 아이콘을 화면에 다시 표시할 수 있습니다. 우리는 당신이 따라갈 수 있는 모든 방법과 홈 화면에 앱 아이콘을 다시 넣을 수 있는 방법에 대해 논의했습니다. 방법 1 - 앱 라이브러리에서 앱 아이콘 바꾸기 앱 라이브러리에서 직접 홈 화면에 앱 아이콘을 배치할 수 있습니다. 1단계 – 옆으로 스와이프하여 앱 라이브러리의 모든 앱을 찾습니다. 2단계 – 이전에 삭제한 앱 아이콘을 찾습니다. 3단계 – 메인 라이브러리의 앱 아이콘을 홈 화면의 올바른 위치로 드래그하기만 하면 됩니다. 이것은 응용 다이어그램입니다

C++에서 클로저는 외부 변수에 액세스할 수 있는 람다 식입니다. 클로저를 생성하려면 람다 표현식에서 외부 변수를 캡처하세요. 클로저는 재사용성, 정보 숨기기, 지연 평가와 같은 이점을 제공합니다. 이는 클로저가 외부 변수가 파괴되더라도 여전히 접근할 수 있는 이벤트 핸들러와 같은 실제 상황에서 유용합니다.

C++ Lambda 표현식은 함수 범위 변수를 저장하고 함수에 액세스할 수 있도록 하는 클로저를 지원합니다. 구문은 [캡처 목록](매개변수)->return-type{function-body}입니다. 캡처 목록은 캡처할 변수를 정의합니다. [=]를 사용하여 모든 지역 변수를 값으로 캡처하고, [&]를 사용하여 모든 지역 변수를 참조로 캡처하거나, [변수1, 변수2,...]를 사용하여 특정 변수를 캡처할 수 있습니다. 람다 표현식은 캡처된 변수에만 액세스할 수 있지만 원래 값을 수정할 수는 없습니다.

클로저는 외부 함수의 범위에 있는 변수에 액세스할 수 있는 중첩 함수입니다. 클로저의 장점에는 데이터 캡슐화, 상태 보존 및 유연성이 포함됩니다. 단점으로는 메모리 소비, 성능 영향, 디버깅 복잡성 등이 있습니다. 또한 클로저는 익명 함수를 생성하고 이를 콜백이나 인수로 다른 함수에 전달할 수 있습니다.

함수 포인터와 클로저가 Go 성능에 미치는 영향은 다음과 같습니다. 함수 포인터: 직접 호출보다 약간 느리지만 가독성과 재사용성이 향상됩니다. 클로저: 일반적으로 느리지만 데이터와 동작을 캡슐화합니다. 실제 사례: 함수 포인터는 정렬 알고리즘을 최적화할 수 있고 클로저는 이벤트 핸들러를 생성할 수 있지만 성능 저하를 가져옵니다.

Java의 클로저를 사용하면 외부 함수가 종료된 경우에도 내부 함수가 외부 범위 변수에 액세스할 수 있습니다. 익명의 내부 클래스를 통해 구현된 내부 클래스는 외부 클래스에 대한 참조를 보유하고 외부 변수를 활성 상태로 유지합니다. 클로저는 코드 유연성을 높이지만 익명 내부 클래스에 의한 외부 변수 참조는 해당 변수를 활성 상태로 유지하므로 메모리 누수의 위험을 인지해야 합니다.

예, 체인 호출 및 클로저를 통해 코드 단순성과 가독성을 최적화할 수 있습니다. 체인 호출은 함수 호출을 유창한 인터페이스에 연결합니다. 클로저는 재사용 가능한 코드 블록을 생성하고 함수 외부의 변수에 액세스합니다.

익명 함수는 간결하고 익명이지만 가독성이 낮고 디버깅이 어렵습니다. 클로저는 데이터를 캡슐화하고 상태를 관리할 수 있지만 메모리 소비 및 순환 참조가 발생할 수 있습니다. 실제 사례: 간단한 수치 처리에는 익명 함수를 사용할 수 있으며 클로저는 상태 관리를 구현할 수 있습니다.
