JavaScript 시리즈에 대한 심층적 이해 (16) Closures_javascript 기술
소개
이 장에서는 JavaScript에서 자주 논의되는 주제인 클로저에 대해 소개하겠습니다. 사실, 모두가 이미 폐쇄에 관해 이야기했습니다. 그럼에도 불구하고 여기서는 이론적 관점에서 클로저에 대해 논의하고 ECMAScript의 클로저가 실제로 내부적으로 어떻게 작동하는지 살펴보겠습니다.
이전 기사에서도 언급했듯이 이 기사들은 일련의 기사이며 서로 연관되어 있습니다. 따라서 본 글에서 소개할 내용을 보다 잘 이해하기 위해서는 먼저 14장의 스코프 체인과 12장의 변수 객체를 읽어보는 것이 좋다.
영문 원문: http://dmitrysoshnikov.com/ecmascript/chapter-6-closures/
소개
ECMAScript 클로저에 대해 직접 논의하기 전에 함수형 프로그래밍을 먼저 살펴볼 필요가 있습니다. 몇 가지 기본 정의.
우리 모두 알고 있듯이 함수형 언어(ECMAScript도 이 스타일을 지원함)에서 함수는 데이터입니다. 예를 들어, 함수를 변수에 할당하거나, 다른 함수에 매개변수로 전달하거나, 함수에서 반환할 수 있습니다. 이러한 함수에는 특별한 이름과 구조가 있습니다.
정의
함수 인수("Funarg") — 값이 함수인 인수입니다.
함수 인수(“Funarg”) — 값이 함수인 인수입니다.
예:
function exampleFunc(funArg ) {
funArg();
}
exampleFunc(function () {
alert('funArg');
})
위의 예에서 funarg의 실제 매개변수는 실제로 exampleFunc에 전달된 익명 함수입니다.
역으로 기능적 매개변수를 받는 함수를 고차 함수(줄여서 HOF)라고 합니다. 함수형 함수 또는 부분적인 수학 이론 또는 연산자라고도 합니다. 위의 예에서 exampleFunc는 그러한 함수입니다.
앞서 언급했듯이 함수는 매개변수뿐만 아니라 반환값으로도 사용될 수 있습니다. 함수를 반환하는 이러한 함수를 함수 값이 있는 함수 또는 함수 값 함수라고 합니다.
(function functionValued() {
return function ( ) {
alert('반환된 함수가 호출됨');
})()()
일반 데이터로 존재할 수 있는 함수(예: 매개변수가 전달될 때, 기능적 매개변수를 받아들이거나 함수 값을 반환할 때)를 일급 함수(일반적으로 일급 객체)라고 합니다.
ECMAScript에서는 모든 함수가 일급 객체입니다.
자신을 매개변수로 받아들이는 함수를 자동 적용 함수 또는 자체 적용 함수라고 합니다.
if (funArg && funArg === selfApplicative) {
alert('self- applicative');
return
}
selfApplicative(selfApplicative);
self를 반환 값으로 사용 이 기능을 자기 복제 기능 또는 자기 복제 기능이라고 합니다. 일반적으로 문헌에서는 "자체 복제"라는 단어가 사용됩니다.
자기 복제 함수의 더 흥미로운 패턴 중 하나는 하나만 허용하는 것입니다. 컬렉션 자체를 승인하는 대신 매개변수로 컬렉션의 항목을 승인합니다.
}
// 사용법
registerModes(['roster', 'accounts', 'groups'] );
//자체 복사 기능 선언
function mode(mode) {
registerMode(mode); // 모드 등록
return 모드;
}
// 사용법, 모드 체인 호출
modes('roster')('accounts')('groups')
//약간 유사함: jQueryObject.addClass ("a") .toggle().removClass("b")
하지만 컬렉션을 직접 전달하는 것은 상대적으로 효과적이고 직관적입니다.
"funarg"가 활성화되면 기능적 매개변수에 정의된 변수에 접근할 수 있습니다. (컨텍스트가 입력될 때마다 컨텍스트 데이터를 저장하는 변수 객체가 생성되기 때문입니다.)
function testFn(funArg) {
//funarg가 활성화되면 local 변수 localVar는 액세스 가능
funArg(10); // 20
funArg(20); // 30
}
testFn(function (arg) {
var localVar = 10;
alert(arg localVar);
});
그러나 우리는 14장에서 ECMAScript에서 함수가 상위 함수에 캡슐화될 수 있다는 것을 알고 있습니다. 상위 함수 컨텍스트. 이 기능은 funarg 문제를 일으킬 수 있습니다.
Funarg 문제
스택 지향 프로그래밍 언어에서는 함수가 활성화될 때마다 이러한 변수와 함수 매개변수가 스택에 푸시됩니다.
함수가 반환되면 이러한 매개변수는 스택에서 제거됩니다. 이 모델은 함수를 기능적 값(예: 상위 함수의 반환 값)으로 사용하는 데 상당한 제한을 둡니다. 대부분의 경우 함수에 자유 변수가 있을 때 문제가 발생합니다.
자유 변수는 함수에서 사용되지만 함수 매개변수도 함수의 지역 변수도 아닌 변수를 말합니다.
예:
function testFn() {
var localVar = 10; innerFn( innerParam) {
alert(innerParam localVar)
}
return innerFn
}
var someFn = testFn()
someFn(20) ); // 30
위의 예에서 innerFn 함수의 경우 localVar는 자유 변수입니다.
스택 지향 모델을 사용하여 로컬 변수를 저장하는 시스템의 경우 이는 testFn 함수 호출이 끝나면 해당 로컬 변수가 스택에서 제거된다는 의미입니다. 이렇게 외부에서 innerFn에 대한 함수 호출이 이루어지면 (localVar 변수가 더 이상 존재하지 않기 때문에) 오류가 발생하게 됩니다.
게다가 위의 예에서 스택 지향 구현 모델에서는 innerFn을 반환 값으로 반환하는 것이 단순히 불가능합니다. testFn 함수의 지역 변수이기도 하므로 testFn이 반환될 때 제거됩니다.
또 다른 문제는 시스템이 동적 범위를 사용하고 함수를 함수 매개변수로 사용하는 경우입니다.
다음 예시(의사코드)를 보세요:
function foo() {
alert(z)
}
foo(); 정적 및 동적 범위 When
(function () {
var z = 20;
foo(); // 10 – 정적 범위 사용, 20 – 동적 범위 사용
})();
// foo를 매개변수로 사용하는 경우에도 마찬가지입니다.
(function (funArg) {
var z = 30;
funArg () ; // 10 – 정적 범위, 30 – 동적 범위
})(foo)
동적 범위, 변수(식별자)를 사용하여 시스템이 관리되는 것을 볼 수 있습니다. 동적 변수 스택을 통해. 따라서 자유 변수는 함수가 생성될 때 저장된 정적 범위 체인이 아닌 현재 활성화된 동적 체인에서 쿼리됩니다.
이로 인해 갈등이 발생합니다. 예를 들어, Z가 여전히 존재하더라도(스택에서 변수를 제거하는 이전 예와는 대조적으로) 여전히 질문이 있습니다. Z의 어떤 값이 다른 함수 호출(어떤 컨텍스트, 어떤 범위에서) 쿼리에 사용됩니까?
위에서는 함수가 반환 값으로 반환되는지 여부(첫 번째 유형의 문제)와 함수를 함수 매개 변수로 사용하는지 여부(두 번째 유형의 문제)에 따라 두 가지 유형의 funarg 문제에 대해 설명합니다. .
위의 문제를 해결하기 위해 폐쇄(closure) 개념이 도입되었습니다.
클로저
클로저는 코드 블록과 코드 블록이 생성된 컨텍스트의 데이터를 결합한 것입니다.
다음 예시(의사코드)를 살펴보겠습니다.
function foo() {
alert(x); // 자유 변수 "x" == 20
}
/ / is foo closure
fooClosure = {
call: foo // 함수 참조
lexicalEnvironment: {x: 20} // 컨텍스트의 컨텍스트 검색
};
위 예에서 "fooClosure" 부분은 의사코드입니다. 이에 따라 ECMAScript에서 "foo" 함수에는 이미 내부 속성, 즉 함수의 컨텍스트를 생성하는 범위 체인이 있습니다.
"lexical"은 일반적으로 생략됩니다. 위의 예는 클로저가 생성되면 컨텍스트 데이터가 저장된다는 점을 강조하기 위한 것입니다. 다음에 함수가 호출되면 저장된(클로저) 컨텍스트에서 자유 변수를 찾을 수 있으며, 위 코드에서 볼 수 있듯이 변수 "z"의 값은 항상 10이 됩니다.
정의에서는 "코드 블록"이라는 더 넓은 용어를 사용하지만 일반적으로 (ECMAScript에서는) 자주 사용하는 함수를 사용합니다. 물론 클로저의 모든 구현이 클로저와 함수를 함께 묶는 것은 아닙니다. 예를 들어 Ruby 언어에서 클로저는 프로시저 객체, 람다 표현식 또는 코드 블록일 수 있습니다.
컨텍스트가 소멸된 후 지역 변수를 저장하려는 목적으로 스택 기반 구현은 당연히 적용되지 않습니다(스택 기반 구조와 충돌하므로). 따라서 이 경우 상위 범위의 클로저 데이터는 가비지 컬렉터(GC라고 하는 가비지 컬렉터) 및 참조 카운팅(참조 카운팅)의 사용과 결합하여 동적으로 메모리를 할당("힙" 구현 기반)하여 구현됩니다. .). 이 구현은 스택 기반 구현보다 성능이 떨어지지만 모든 구현은 항상 최적화될 수 있습니다. 함수가 자유 변수, 기능 매개변수 또는 기능 값을 사용하는지 분석한 다음 상황에 따라 결정할 수 있습니다. 스택 또는 힙에 있습니다.
ECMAScript 클로저 구현
이론적인 부분을 논의한 후 ECMAScript에서 클로저를 구현하는 방법을 소개하겠습니다. 여기서 다시 강조할 가치가 있습니다. ECMAScript는 정적(어휘적) 범위만 사용합니다(Perl과 같은 언어는 변수 선언에 정적 범위와 동적 범위를 모두 사용할 수 있습니다).
var x = 10; 🎜>function foo() {
alert(x);
}
(function (funArg) {
var x = 20;
// 변수 "x "(어휘적) 컨텍스트에 저장된 정적, 함수 생성 시 저장됨
funArg() // 20 대신 10
})(foo); >
기술적으로 함수를 생성한 상위 컨텍스트의 데이터는 함수의 내부 속성 [[Scope]]에 저장됩니다. [[범위]]가 무엇인지 모른다면 [[범위]]에 대해 매우 자세하게 소개되어 있는 14장을 먼저 읽어 보시기 바랍니다. [[Scope]] 및 범위 체인 지식을 완전히 이해했다면 클로저도 완전히 이해할 것입니다.
함수 생성 알고리즘에 따르면 ECMAScript에서 모든 함수는 생성 시 상위 컨텍스트의 범위 체인을 저장하기 때문에 클로저임을 알 수 있습니다(예외 제외). 나중에 활성화됨 - [[Scope]]는 함수가 생성될 때 거기에 있을 것입니다.):
코드 복사
}
// foo는 클로저
foo:
[[Call]]:
[[Scope]]: [
global: {
x: 10
}
],
... // 기타 속성
}
앞서 말했듯이 최적화 목적으로 함수를 사용하지 않는 경우 자유 변수의 경우 구현이 부작용 도메인 체인에 저장되지 않을 수 있습니다. 그러나 ECMA-262-3 사양에는 아무 것도 언급되어 있지 않습니다. 따라서 일반적으로 모든 매개변수는 생성 단계에서 [[Scope]] 속성에 저장됩니다.
일부 구현에서는 클로저 범위에 직접 액세스할 수 있습니다. 예를 들어, Rhino에는 12장에서 소개된 함수의 [[Scope]] 속성에 대한 비표준 __parent__ 속성이 있습니다.
코드 복사
var y = 20;
반환 함수() {
alert(y)
};
foo(); // 20
alert(foo.__parent__.y); // 20
foo.__parent__.y = 30
foo(); 🎜>// 범위 체인을 통해 최상위로 이동할 수 있습니다.
alert(foo.__parent__.__parent__ === global); // true
alert(foo.__parent__.__parent__.x) // 10
모든 객체는 [[Scope]]를 참조합니다.
또한 여기에 참고하세요: ECMAScript에서는 동일한 상위 컨텍스트에서 생성된 클로저가 [[Scope]] 속성을 공유합니다. 즉, [[Scope]] 변수에 대한 특정 클로저에 의한 수정은 다른 클로저에 의한 변수 읽기에 영향을 미칩니다:
즉, 모든 내부 함수는 동일한 상위 범위를 공유합니다. 🎜>
var secondClosure; 🎜>
function foo() {
var x = 1;
firstClosure = function() { return x }; x; };
x = 2; // 2개의 클로저가 공유하는 [[Scope]]에 영향을 미칩니다.
alert(firstClosure()) // 3 , 첫 번째 클로저의 [[Scope]]
}
foo()
alert(firstClosure()) // 4
Alert(secondClosure()); // 3
이 함수에 대해 매우 흔한 오해가 있습니다. 개발자는 루프 문에서 함수를 생성할 때(내부적으로 계산) 결과를 얻지 못하는 경우가 많습니다. 그 자체의 가치.
alert(k)
}
data[0](); // 0이 아닌 3
data[1](); // 1이 아닌 3
data[2]() // 2가 아닌 3
위의 예는 동일한 컨텍스트에서 생성된 클로저가 [[Scope]] 속성을 공유한다는 것을 증명합니다. 따라서 상위 컨텍스트의 변수 "k"는 쉽게 변경될 수 있습니다.
코드 복사
data[0].[[Scope]] == = 범위;
data[1].[[범위]] === 범위;
data[2].[[범위]] === 범위
방식으로, 기능이 활성화되면 최종적으로 사용되는 k는 3이 됩니다. 아래와 같이 클로저를 생성하면 이 문제를 해결할 수 있습니다.
코드 복사
alert(x);
};
})(k) // "k" 값을 전달합니다.
}
// 이제 결과는 다음과 같습니다. 올바른
data[0](); // 0
data[1](); // 1
data[2]() // 2
위 코드에서 어떤 일이 일어나는지 살펴볼까요? "_helper" 함수가 생성된 후 매개변수 "k"를 전달하여 활성화됩니다. 반환 값도 함수이며 해당 배열 요소에 저장됩니다. 이 기술은 다음과 같은 효과를 생성합니다. 함수가 활성화되면 "_helper"가 매개변수 "x"를 포함하는 새 변수 개체를 생성할 때마다 "x" 값은 전달된 "k" 값이 됩니다. 이렇게 하면 반환되는 함수의 [[Scope]]는 다음과 같습니다.
코드 복사
data[1].[[Scope]] === [
... // 기타 변수 객체
상위 컨텍스트의 활성 객체 AO: {data: [...], k: 3},
_helper 컨텍스트의 활성 객체 AO: {x : 1 }
];
data[2].[[Scope]] === [
... // 기타 변수 객체
상위 컨텍스트의 활성 객체 AO : {data : [...], k: 3},
_도우미 컨텍스트의 활성 개체 AO: {x: 2}
]
이때 함수의 [[Scope]] 속성이 정말 원하는 값을 가지고 있음을 알 수 있습니다. 이 목적을 달성하려면 [[Scope]]에 추가 변수 개체를 생성해야 합니다. 반환된 함수에서 "k" 값을 얻으려는 경우 값은 여전히 3이라는 점에 유의해야 합니다.
그런데 JavaScript를 소개하는 글에서는 추가로 생성된 함수만 클로저라고 생각하는 경우가 많은데 이는 잘못된 것입니다. 실제로는 이 방법이 가장 효과적입니다. 그러나 이론적 관점에서 보면 ECMAScript의 모든 함수는 클로저입니다.
그러나 위에서 언급한 방법만이 전부는 아닙니다. "k"의 올바른 값은 다음과 같은 다른 방법으로도 얻을 수 있습니다.
var data = [];
for (var k = 0; k (data[k] = function () {
alert (arguments.callee.x);
}).x = k; // k를 함수의 속성으로 사용
}
// 결과도 정확합니다
data[0] (); // 0
data[1](); // 1
data[2](); // 2
Funarg 및 반환
클로저에서 또 다른 기능이 반환됩니다. ECMAScript에서 클로저의 return 문은 호출 컨텍스트(호출자)로 제어 흐름을 반환합니다. Ruby와 같은 다른 언어에는 다양한 형태의 클로저가 있으며 해당 클로저 반환도 다릅니다. 다음 방법이 가능합니다. 호출자에게 직접 반환되거나 경우에 따라 컨텍스트에서 직접 종료됩니다. .
ECMAScript 표준 종료 동작은 다음과 같습니다.
function getElement() {
[1, 2, 3].forEach(함수(요소) {
if(요소 % 2 == 0) {
// "forEach" 함수로 복귀
// getElement 함수로 복귀하는 대신
alert('found: ' element); // 발견: 2
return element; >
} );
return null;
}
그러나 ECMAScript의 try catch를 통해 다음과 같은 효과를 얻을 수 있습니다.
try {
[1, 2, 3].forEach(함수 (요소) {
if (요소 % 2 == 0) {
// // getElement에서 반환 "
alert('found: ' 요소); // 발견: 2
$break.data = element;
throw $break;
}
});
} catch (e) {
if (e == $break) {
return $break.data;
}
return null;
}
alert(getElement()); // 2
이론적인 버전
여기서는 개발자가 클로저를 다음과 같이 잘못 이해하는 경우가 많다는 점을 설명하겠습니다. 상위 컨텍스트에서 단순화됨 내부 함수를 반환하면 익명 함수만 클로저가 될 수 있다는 것도 이해합니다.
다시 말하지만, 범위 체인으로 인해 모든 함수는 클로저입니다(함수 유형에 관계없이 익명 함수, FE, NFE 및 FD는 모두 클로저입니다).
이 문제를 더 명확하게 하기 위해 ECMAScript의 클로저 정의에 대한 두 가지 올바른 버전을 제공합니다.
ECMAScript에서 클로저는 다음을 의미합니다.
이론적인 관점에서 : 모든 기능. 왜냐하면 모두 생성 시 상위 컨텍스트의 데이터를 저장하기 때문입니다. 이는 간단한 전역 변수의 경우에도 마찬가지입니다. 함수에서 전역 변수에 액세스하는 것은 자유 변수에 액세스하는 것과 동일하기 때문입니다.
실용적인 관점에서 볼 때: 다음 함수는 클로저로 간주됩니다.
생성된 컨텍스트가 파괴되더라도 여전히 존재합니다(예: 내부 함수가 상위 함수에서 반환됨)
무료 변수는 코드에서 참조됩니다
클로저의 실제 사용
실제로 사용하면 클로저는 funarg에 정의된 다양한 계산 방법을 사용자 정의할 수 있어 매우 우아한 디자인을 만들 수 있습니다. 다음은 정렬 조건 함수를 매개변수로 받는 배열 정렬의 예입니다.
코드 복사
같은 예도 그렇습니다. 배열의 맵 메소드는 함수에 정의된 조건에 따라 원래 배열을 새 배열에 매핑합니다.
코드 복사
기능적 매개변수를 사용하면 검색 방법을 쉽게 구현하고 무제한 검색 조건을 지원할 수 있습니다.
someCollection.find(function (element) {
return element.someProperty == 'searchCondition';
})
있습니다. 각 배열 요소에 함수를 적용하는 일반적인 forEach 메서드와 같은 응용 프로그램 함수도 있습니다.
[1, 2, 3].forEach(함수(요소) {
if(요소 % 2 != 0) {
alert(요소);
}
}); // 1, 3
그런데 함수 객체의 적용 및 호출 메소드는 함수형 프로그래밍에서 응용 함수로도 사용할 수 있습니다. 여기서 "this"에 대해 논의할 때 apply와 call이 이미 소개되었습니다. 우리는 이를 응용 프로그램 함수, 즉 인수(적용의 인수 목록, 호출의 개별 인수)에 적용되는 함수로 생각합니다.
(function () {
alert([] .join.call (인수, ';')); // 1;2;3
}).apply(this, [1, 2, 3])
클로저 또 다른 매우 중요한 것이 있습니다. 애플리케이션 - 지연된 통화:
var a = 10 ;
setTimeout(function () {
alert(a); // 10, 1초 후
}, 1000)
콜백 함수도 있습니다
//...
var x = 10 ;
// 예를 들어
xmlHttpRequestObject.onreadystatechange = function () {
// 데이터가 준비되면 호출됩니다.
// 여기서는 어떤 컨텍스트에서 생성되든 상관없습니다.
// 현재 변수 "x"의 값이 이미 존재합니다.
alert(x) // 10
}//...
// 초기화
(함수(객체) {
var x = 10;
object.getX = function _getX () {
return x;
})(foo)
alert(foo.getX());
요약
기타 참고자료

핫 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)

뜨거운 주제









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

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

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

제목: 클로저로 인한 메모리 누수 및 솔루션 소개: 클로저는 내부 함수가 외부 함수의 변수에 액세스할 수 있도록 하는 JavaScript에서 매우 일반적인 개념입니다. 그러나 클로저를 잘못 사용하면 메모리 누수가 발생할 수 있습니다. 이 문서에서는 클로저로 인해 발생하는 메모리 누수 문제를 살펴보고 솔루션과 구체적인 코드 예제를 제공합니다. 1. 클로저로 인한 메모리 누수 클로저의 특징은 내부 함수가 외부 함수의 변수에 접근할 수 있다는 것입니다. 즉, 클로저에서 참조되는 변수는 가비지 수집되지 않습니다. 부적절하게 사용하는 경우,

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

클로저에서 메모리 누수를 방지하는 방법은 무엇입니까? 클로저는 함수 중첩 및 데이터 캡슐화를 가능하게 하는 JavaScript의 가장 강력한 기능 중 하나입니다. 그러나 클로저는 특히 비동기 및 타이머를 처리할 때 메모리 누수가 발생하기 쉽습니다. 이 문서에서는 클로저에서 메모리 누수를 방지하는 방법을 설명하고 구체적인 코드 예제를 제공합니다. 메모리 누수는 일반적으로 객체가 더 이상 필요하지 않지만 어떤 이유로 객체가 차지하는 메모리를 해제할 수 없을 때 발생합니다. 클로저에서 함수가 외부 변수를 참조하고 이러한 변수는

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

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