JS 폐쇄
폐쇄 전에 알아야 할 것
1. 함수 범위
(1). JS 언어의 특별한 특징은 글로벌 변수가 함수 내에서 직접 읽을 수 있다는 것입니다.
코드 사본은 다음과 같습니다.
<script type = "text/javaScript">
var n = 100;
기능 부모 () {
경고 (n);
}
부모 (); // 100
</스크립트>
PHP에있는 경우
코드 사본은 다음과 같습니다.
<? php
$ n = 100;
기능 부모 () {
echo $ n;
}
parent (); // 오류가보고되지 않습니다. n은 정의되지 않았습니다
?>
(2). 함수 내부의 로컬 변수는 함수 밖에서 읽을 수 없습니다.
코드 사본은 다음과 같습니다.
<script type = "text/javaScript">
기능 부모 () {
var m = 50;
}
조상();
경고 (m); // 오류 m은 정의되지 않았습니다
</스크립트>
내부적으로 변수를 선언 할 때 Var를 추가해야합니다. 그렇지 않으면 전역 변수가 선언됩니다.
코드 사본은 다음과 같습니다.
기능 부모 () {
m = 50;
}
조상();
경고 (m); // 50
// 물론 이것은 PHP에서 더욱 그렇습니다.
코드 사본은 다음과 같습니다.
<? php
기능 부모 () {
글로벌 $ m; // 글로벌, 정의 및 할당을 분리해야합니다
$ m = 50;
}
조상();
echo $ m; // 50
?>
// 전역이없는 경우 정의 오류가 없습니다.
때로는 함수 내에서 로컬 변수를 얻어야하는 경우 JS 변수 범위의 특성을 사용해야합니다. 예를 들어, 함수 내에서 하위 함수 정의, 자식 함수의 경우 부모 함수는 전역이며, 자식 함수는 부모 함수의 변수에 액세스 할 수 있습니다 (전체 JS 코드의 경우 로컬 변수입니다).
코드 사본은 다음과 같습니다.
<script type = "text/javaScript">
기능 부모 () {
var m = 50;
기능 아들 () {
경고 (m);
}
돌아 오는 아들;
}
var s = parent (); // 결과를 전역적으로 저장합니다
s (); // 50
</스크립트>
부모 내의 모든 로컬 변수는 자식 기능으로 보이지만 자녀 기능 내의 로컬 변수는 부모 기능에 보이지 않습니다. 이것은 JS에 고유 한 체인 범위 구조입니다. Child Object는 모든 상위 물체의 변수를 레벨별로 조회합니다. 부모 객체의 모든 변수는 자식 객체에 보입니다. 그렇지 않으면 맞지 않습니다! 위의 아들 기능은 폐쇄입니다
어떤 학생들은 이것을 할 수 있습니다
코드 사본은 다음과 같습니다.
기능 부모 () {
var m = 50;
기능 아들 () {
경고 (m);
}
}
조상();
SON () // 기능 아들은 정의되지 않았습니다
JavaScript에서 함수에서 선언 된 함수는 로컬이며 함수가 실행 된 후에 해제됩니다.
이것과 PHP의 차이에주의하십시오
코드 사본은 다음과 같습니다.
<? php
기능 부모 () {
기능 아들 () {
$ m = 50;
에코 $ m;
}
}
조상();
SON (); // output 50은 오류를보고하지 않습니다
?>
폐쇄
함수 내부 및 외부 함수를 연결하는 함수, 브리지를 내부 정의
클로저에는 두 가지 기능이 있습니다.
먼저, 앞서 언급 한 변수 내부의 읽기 기능
두 번째는 이러한 변수의 값을 메모리에 저장하여 데이터 공유를 실현하는 것입니다.
다음은 폐쇄의 몇 가지 예입니다
코드 사본은 다음과 같습니다.
<script type = "text/javaScript">
var cnt = (function () {
var i = 0;
return function () {
경고 (i);
i ++;
}
}) ();
cnt (); // 0
cnt (); // 1
cnt (); // 2
cnt (); // 3
</스크립트>
메모리에서 익명 함수의 실행 결과 (즉, 하위 기능 선언을 글로벌 변수 컷에 할당 함)의 실행 결과를 저장합니다.
cut ()을 실행할 때 값은 메모리에서 직접 검색됩니다. CNT () 함수 만 호출 할 수 있으며 직접 경고 할 수 없습니다 (i)
매개 변수를 폐쇄로 전송할 수도 있습니다
코드 사본은 다음과 같습니다.
var cnt = (function (num) {
return function () {
경고 (num);
Num ++;
}
}) (5);
cnt (); // 5
cnt (); // 6
cnt (); // 7
// 물론 호출 할 때 매개 변수를 전달할 수도 있습니다
var cnt = (function () {
var i = 0;
반환 함수 (num) {
num+= i;
경고 (num);
i ++;
}
}) ();
cnt (1); // 1
cnt (2); // 3
CNT (3); // 5
클로저를 더 잘 이해하기 위해 다음 코드를 살펴 봅니다.
예를 들어, 배열에 5 개의 함수가있는 배열을 반환하고, 첫 번째 함수는 0, 두 번째 함수는 팝업 1 ...
코드가 다음과 같이 작성된 경우
코드 사본은 다음과 같습니다.
함수 박스 () {
var arr = [];
for (i = 0; i <5; i ++) {
arr = function () {return i;}
}
반환 ARR;
}
var a = box ();
경고 (a); // 5 개의 함수 본체를 포함하는 배열
경고 (A [0] ());
경고 (A [1] ());
팝업 기능 본문
function () {return i;}}
마지막으로, 이것은 4이고 ++는 5가됩니다.
루프 중지 용
우리의 요구 사항을 충족시키지 못한 모든 팝업 5가 발견되었습니다.
해결책 1
내부 기능의 자기 실행
코드 사본은 다음과 같습니다.
함수 박스 () {
var arr = [];
for (i = 0; i <5; i ++) {
arr = (함수 (num) {return i;}) (i);
}
반환 ARR;
}
var a = box ();
for (var i = 0; i <a.length; i ++) {
경고 (a);
}
그러나 반환 된 배열의 요소가 함수 실행의 결과라는 것을 발견했지만, 우리가 원하는 것은 함수를 업그레이드해야한다는 것입니다.
해결책 2
폐쇄 구현
코드 사본은 다음과 같습니다.
함수 박스 () {
var arr = [];
for (var i = 0; i <5; i ++) {
arr = (함수 (num) {
return function () {return num;}
})(나);
}
반환 ARR;
}
var arr = box ();
for (var i = 0; i <5; i ++) {
경고 (ARR ()); // 0,1,2,3,4
}
키 코드
코드 사본은 다음과 같습니다.
arr = (함수 (num) {
return function () {return num;}
})(나);
i = 0 일 때
arr [0] = (function (num) {return function () {return num;}}) (0);
1시
arr [1] = (function (num) {return function () {return num;}}) (1);
위는 폐쇄의 이점입니다! 매우 간단하고 실용적입니다.