폐쇄란 무엇인가요?
클로저란 무엇인가요? 클로저는 정적 언어에는 없는 새로운 기능입니다. 그러나 클로저는 이해하기에는 너무 복잡한 것이 아닙니다. 즉, 클로저는 함수의 지역 변수 집합이지만 이러한 지역 변수는 함수가 반환된 후에도 계속 존재합니다. 클로저는 함수가 반환된 후 함수의 "스택"이 해제되지 않음을 의미합니다. 또한 이러한 함수 스택은 스택에 할당되지 않고 힙에 할당된다는 것도 이해할 수 있습니다. 함수 내에 다른 함수가 정의되면 클로저가 발생합니다. . 가방.
클로저 = 함수 내부에서 생성된 함수(또는 줄여서 내부 함수) + 함수가 생성되었을 때의 환경 정보
따라서 클로저는 익명 함수와 동일하지 않습니다. 어떤 사람들은 이 함수를 함수 클로저 함수 내부에서 생성되었다고 부르지만 저는 실제로는 정확하지 않다고 생각하세요.
다음 코드를 살펴보겠습니다.
function init() { var name = "Zilongshanren"; // name 是在 init 函数里面创建的变量 // displayName() 是一个内部函数,即一个闭包。注意,它不是匿名的。 function displayName() { console.log(name); } //当 displayName 函数返回后,这个函数还能访问 init 函数里面定义的变量。 return displayName; } var closure = init(); closure(); Zilongshanren undefined
displayName은 init 함수 내부에서 생성된 함수입니다. 여기에는 name 변수와 같은 init 함수의 내부 범위에 대한 모든 정보가 포함됩니다. displayName 함수가 반환되면 함수 자체가 생성 당시의 환경 정보, 즉 init 함수의 name 변수를 전달합니다.
클로저는 무엇을 하나요?
클로저가 무엇인지 이해한 후 다음과 같이 질문할 수 있습니다. 이해하기 너무 어려운데, 그 용도는 무엇입니까?
JS에서는 프라이빗 속성과 메서드를 정의하는 프라이빗 키워드가 있는 Java나 C++와는 달리 프라이빗 메서드를 생성할 방법이 없기 때문입니다. JS에서는 함수만 자신의 범위에 속하는 객체를 생성할 수 있습니다. JS에는 블록 범위가 없습니다. 이에 대해서는 나중에 자세히 소개하기 위해 또 다른 글을 쓰겠습니다.
모든 프로그래밍 베테랑은 프로그램을 잘 작성하려면 캡슐화와 추상화를 잘 사용해야 한다는 것을 알고 있습니다! 개인 속성과 메서드를 정의할 수 없다는 것은 캡슐화와 추상화를 전혀 사용할 수 없다는 것을 의미합니다. . .
개인적인 것을 정의할 수 없으며 모든 변수와 함수는 공개됩니다. 분명히 문제가 있습니다. 글로벌은 악입니다!
클로저는 우리의 구세주입니다!
다음 코드를 살펴보겠습니다.
var makeCounter = function() { var privateCounter = 0; function changeBy(val) { privateCounter += val; } return { increment: function() { changeBy(1); }, decrement: function() { changeBy(-1); }, value: function() { return privateCounter; } } }; var counter1 = makeCounter(); var counter2 = makeCounter(); console.log(counter1.value()); /* Alerts 0 */ counter1.increment(); counter1.increment(); console.log(counter1.value()); /* Alerts 2 */ counter1.decrement(); console.log(counter1.value()); /* Alerts 1 */ console.log(counter2.value()); /* Alerts 0 */ 0 2 1 0 undefined
여기의 privateCounter 변수와 ChangeBy는 모두 비공개이며 makeCounter 함수 외부에서는 완전히 보이지 않습니다. 이러한 방식으로 makeCounter를 통해 생성한 개체는 모든 개인 데이터와 개인 메서드를 숨깁니다.
이것으로 생각나는 것이 있나요?
하하 이거 그냥 OO아닌가요? 데이터 운영을 위한 데이터와 메소드를 캡슐화한 후 공개 인터페이스 호출을 통해 데이터 처리를 완료합니다.
물론 프로토타입 상속을 사용하여 OO를 구현할 수도 있다고 말할 수도 있습니다. 예, 그것이 우리를 포함하여 현재 대부분의 사람들이 하는 일입니다. 그러나 상속은 항상 이해하기가 매우 어렵습니다. 코드 조각을 이해하려면 모든 상속 체인을 이해해야 하기 때문입니다. 코드에 버그가 있으면 디버깅하기가 매우 어렵습니다.
아주 먼 이야기입니다. 클로저를 올바르게 사용하는 방법을 살펴보겠습니다.
클로저를 올바르게 사용하는 방법은 무엇입니까?
클로저는 메모리를 점유하고 js 엔진의 실행 효율성에도 영향을 미칩니다. 따라서 코드가 자주 실행되는 경우 이 코드에서 클로저 사용을 신중하게 고려해야 합니다.
객체를 생성하는 함수를 살펴보겠습니다.
function MyObject(name, message) { this.name = name.toString(); this.message = message.toString(); this.getName = function() { return this.name; }; this.getMessage = function() { return this.message; };} var myobj = new MyObject(); var myobj = new MyObject();
새 객체를 생성하기 위해 호출될 때마다 두 개의 클로저가 생성됩니다. 프로그램에 이러한 MyObject 개체가 수천 개 있으면 훨씬 더 많은 메모리를 차지하게 됩니다.
올바른 접근 방식은 프로토타입 체인을 사용하는 것입니다.
function MyObject(name, message) { this.name = name.toString(); this.message = message.toString(); } MyObject.prototype.getName = function() { return this.name; }; MyObject.prototype.getMessage = function() { return this.message; }; var myobj = new MyObject();
이제 MyObject 프로토타입에는 두 개의 메서드가 정의되어 있습니다. new를 통해 개체를 만들면 이 두 메서드는 프로토타입에 하나의 복사본만 갖게 됩니다.
클로저 성능은 어떤가요?
클로저도 함수이지만 추가적인 환경 정보를 저장하기 때문에 이론적으로는 순수 함수보다 더 많은 메모리를 차지하며 JS 엔진은 클로저를 해석하고 실행할 때 더 많은 메모리를 소비합니다. 하지만 이들 간의 성능 차이는 3%~5% 정도입니다. (구글에서 얻은 데이터라 정확하지 않을 수 있습니다.)
하지만 폐쇄의 이점은 확실히 큽니다. 버그를 방지하려면 클로저와 상태 비저장 프로그래밍을 더 많이 사용하세요.
클로저를 이해하면 FP 패러다임의 Js 클래스 라이브러리 대부분과 그 뒤에 숨겨진 디자인 아이디어를 이해할 수 있습니다. 물론 클로저만으로는 충분하지 않습니다. FP, 무국적, 람다 계산과 같은 개념도 세뇌해야 합니다.
이 글을 마친 후 모든 분들이 js 클로저에 대해 이해하시길 바랍니다.
관련 추천:
위 내용은 Javascript의 클로저란 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!