먼저 Wikipedia의 정의를 살펴보겠습니다
컴퓨터 과학에서 클로저(영어: Closure)는 어휘 클로저(Lexical Closure) 또는 함수 클로저(function closure)라고도 알려져 있으며 자유 변수 함수를 나타냅니다. 참조된 자유 변수는 그것이 생성된 환경을 떠난 후에도 함수에 남아 있습니다. 따라서 클로저는 함수와 관련 참조 환경으로 구성된 엔터티라고 말하는 또 다른 방법이 있습니다. 클로저는 런타임에 여러 인스턴스를 가질 수 있으며, 서로 다른 참조 환경과 동일한 함수 조합이 서로 다른 인스턴스를 생성할 수 있습니다.
이 문장을 간단히 이해하려면 두 가지 핵심 사항이 있습니다.
1. 자유 변수 2. 함수(자유 변수 참조).
변수를 정의할 때 제약 조건을 지정하지 않으면 이는 자유 변수입니다. 예:
x ∈ (0,99) f(x,y)
함수 f(x,y)에서 x는 제약 변수이고 y는 자유 변수입니다.
특히 JavaScript의 경우 예를 살펴보세요.
var x = 0; function foo (y) { var z = 2; return x + y + z;}foo (3); // 3
수학적 사고로 변환하면 foo 함수는 실제로 foo(x,y)와 같아야 하지만 함수의 매개변수는 실제로 제한되어 있다는 것을 알고 있습니다. 즉, 실제 자유 변수는 x뿐입니다.
이것은 간단한 정의로 이어질 수 있습니다. 함수에서 지역 변수도 형식 매개변수도 아닌 변수가 있으면 클로저를 형성한다고 생각하면 됩니다.
거의 모든 언어에서는 동일한 이름을 가진 변수가 가장 가까운 위치에서 검색됩니다. 먼저 이 범위에서 검색되지 않으면 상위 범위로 이동합니다. 우리는 이것을 범위 체인이라고 부릅니다.
클로저 함수에서 자유 변수는 일반적으로 상위 변수에 의해 제공됩니다. 다음 예를 보세요:
function foo(x) { var tmp = 3; function bar(y) { console.log(x + y + (++tmp)); } bar(10);}foo(2)
위의 정의에 따르면 bar에는 자유 변수가 있고 클로저이지만 foo는 그렇지 않습니다.
그렇다면 foo를 어떻게 폐쇄할 수 있을까요?
var x = 0;function foo() { var tmp = 3; function bar(y) { console.log(x + y + (++tmp)); } bar(10);}// 其实转换一下,形如function foo2() { var tmp = 3; //function bar(y) { console.log(x + 10 + (++tmp)); //} // bar(10);}
이 시점에서 foo는 클로저로 간주될 수 있습니다.
이쯤 되면, 몇몇 친구들은 이것이 우리가 일반적으로 보는 js 클로저와 다르다고 생각할 수도 있습니다. 예제는 이 블로그에서 가져온 것입니다
function foo(x) { var tmp = new Number(3); return function (y) { alert(x + y + (++tmp)); }}var bar = foo(2); // bar 现在是一个闭包bar(10);
이 함수는 실제로 다시 작성될 수 있습니다.
bar = function (y) { // foo(2) alert(2 + y + (++tmp))}
분명히 tmp는 원래 정의를 따르는 자유 변수이고 bar는 자유 변수가 있는 함수입니다.
그렇다면 tmp는 어디에 존재하는 걸까요?
foo(2)가 실행되면 tmp=3인 변수가 생성됩니다. 이 변수는 반환 함수에서 참조되므로 재활용되지 않습니다. 반환 함수의 자유 변수는 범위 체인에 따라 값을 찾습니다. bar 함수는 foo(2)에 정의되어 있으므로 foo(2)의 변수 영역에서 먼저 변수 tmp를 찾아 연산한다.
참고: 스코프 체인 문제에 대해서는 다음 글에서 분석하겠습니다.
그러고보니 모듈 모드를 삽입해 보세요.
var Module = (function () { var aaa = 0; var foo = function () { console.log(aaa); } return { Foo: foo }})();// 或者(function () { var aaa = 0; var foo = function () { console.log(aaa); } window.Module = { Foo: foo }})();
위의 두 가지 예에 유의하세요. 모듈 자체는 객체일 뿐이지만 반환 함수 자체는 클로저를 형성하여 범위가 깨끗하고 다른 함수를 오염시키지 않도록 합니다.
이렇게 말하면 몇몇 친구들은 이것이 대체 카테고리라고 생각할까요? 지역 변수와 접근 가능한 함수를 갖습니다. 네, 외관상으로는 클로저와 클래스가 매우 유사하다고 생각합니다.
Java를 예로 들어 보겠습니다.
class Foo { private int a; int Say( int b ) { return a + b; } }
위 Foo에서 Say 함수의 a는 함수 범위 밖에 있으며 자유 변수입니다. Say는 함수 클로저를 형성하는 것으로 간주될 수 있습니다. 하지만 js와 다른 점은 클래스의 인스턴스, 즉 객체를 통해 인스턴스 메소드를 호출해야 한다는 점입니다.
Java 설계에서는 액세스 권한, 개인, 보호, 기본 및 패키지가 명확하게 정의되어 있습니다. 이는 호출 표준화의 선구적인 작업입니다. 또한 변수와 함수에는 액세스 권한을 정의하고 각 클래스에 속하기 위한 키워드가 있어 명확하고 명확하기 때문에 Java 프로그래머는 클로저 구현을 거의 고려하지 않습니다.
클래스 구현 측면에서 클로저를 이해하면 클로저 사용을 권장하지 않는 이유를 쉽게 이해할 수 있습니다.
클로저가 호출될 때마다 클로저 함수에 필요한 일부 자유 변수를 저장하기 위한 범위가 생성됩니다. 이로 인해 메모리 낭비가 쉽게 발생할 수 있습니다. Java 프로그래밍에서도 아무렇게나 새로운 객체를 생성하는 것은 권장되지 않습니다.
전 글에서 바인딩, 호출, 적용이라는 점을 언급했는데, 객체 지향적이기 때문에 이것을 바인딩할 필요가 있습니다.
객체지향에 있어서 객체지향의 장점은 이해하기 쉽고, 유지하기 쉽고, 재사용하기 쉽다는 점이라고 생각합니다. 이는 여러 사람이 대규모 프로젝트를 개발할 때의 성능 요구 사항을 훨씬 초과합니다.
무어의 법칙이 느려지고 있는 지금도 메모리는 예전에 비해 매우 저렴하기 때문에 고대부터 성능 요구 사항이 극심했고, 이제는 코드 가독성이 일반적으로 옹호되고 있습니다.
이 다채로운 코드의 세계를 만들어낸 슈퍼 전문가들이 있습니다. 더 많은 사람들이 프로그래밍의 즐거움을 경험할 수 있도록 프로그래밍 언어를 이해하기 쉽게 설계하고 다양한 컴파일러와 파서를 발명했습니다...
만약 1+1 프로그램을 작성하면 객체 지향이 필요하지 않습니다. 인간이 기계와 함께 슈퍼 로직과 메모리를 가질 수 있다면 객체 지향이 필요하지 않습니다.
위 내용은 js의 클로저와 클래스를 이해하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!