초보자가 JavaScript 클로저를 이해할 수 있도록 가장 이해하기 쉬운 코드를 사용하십시오.

WBOY
풀어 주다: 2016-05-16 17:55:42
원래의
995명이 탐색했습니다.

최근에 인기 있는 Uncle Tom 시리즈와 "Javascript Advanced 프로그래밍" 기사를 포함하여 JavaScript 클로저에 관한 여러 기사를 읽었습니다... 거기에 포함된 코드 중 일부는 대학 교과서에서 가져온 것입니다. 읽지 마세요. 천국에서 온 책 같아요. 다행스럽게도 최근에 "ppk on javascript"와 "객체 지향 JavaScript"라는 두 권의 좋은 책을 접했습니다. 후자는 아직 중국어 버전이 없지만 전자는 여전히 원본 버전을 읽는 것이 좋습니다. .글은 복잡하지 않습니다. 관심있는 친구들이 읽을 수 있습니다. 봐, 발전하고 싶은 친구들에게 적합합니다.
오늘은 이 두 권의 책을 결합하여 가장 간단한 언어와 가장 대중적인 방식으로 JavaScript 클로저에 대해 이야기하겠습니다. 저도 초보자이므로 실수가 있으면 지적해 주세요.
1. 준비 지식
1. 함수의 매개변수로서의 함수
자바스크립트를 배울 때 항상 다른 언어와는 다른 개념을 가지고 있어야 합니다. ​​​​: 함수(function)는 특별한 것이 아니라 일종의 데이터이기도 합니다. bool, string, number도 다르지 않습니다.
함수의 매개변수는 다음과 같이 문자열, 숫자, 부울일 수 있습니다.
function(a, b) {return a b;}
그러나 함수를 전달할 수도 있습니다. 내 말을 제대로 들었습니다. 함수의 매개변수는 함수입니다! 다음 두 가지 기능을 결합하세요.

코드 복사 코드는 다음과 같습니다.

// 3개 배치 숫자 두 배
function MultiplyByTwo(a, b, c) {
var i, ar = []
for(i = 0; i < 3; i ) {
ar; [i] = 인수[i] * 2;
}
return ar;
}

코드 복사 코드는 다음과 같습니다.

//숫자를 하나씩 더합니다.
function addOne(a) {
return a 1; 🎜>

그런 다음


코드를 복사하세요. 코드는 다음과 같습니다.
var myarr = [] ;
//먼저 루프를 사용하여 각 숫자에 2를 곱합니다.
myarr = MultiplyByTwo(10, 20, 30)
//다음을 사용하여 각 숫자에 1을 더합니다. 또 다른 루프
for (var i = 0; i < 3; i ) {myarr[i] = addOne(myarr[i]);}


이 프로세스에 유의해야 합니다. 실제로 사용합니다. 두 루프 사이에는 여전히 개선의 여지가 있으므로 다음을 수행하는 것이 좋습니다.


function MultiplyByTwo(a, b, c, addOne) {
var i, ar = []
for(i = 0; i < 3; i ) {
ar[i] = addOne (arguments[i] * 2);
}
return ar;
}


이런 식으로 함수가 전달됩니다. 매개변수로 입력하고 첫 번째 루프에서는 직접 호출합니다. 그런 함수가 바로 유명한 콜백 함수
2. 반환값으로서의 함수
함수에는 반환값이 있을 수 있지만 일반적으로 우리는

과 같은 숫자값 반환에 익숙하다.
function ex(){
return 12
}


하지만 함수가 일종의 데이터일 뿐이라는 사실을 깨닫고 나면 함수를 반환하는 것도 생각해 볼 수 있습니다. 다음 기능에 주의하세요.


function a () {
alert('A!');
return function(){
alert('B!')
}


"B!"를 표시하는 함수를 반환합니다. 다음 사용:


코드 복사 코드는 다음과 같습니다. var newFunc = a ();
newFunc()


결과는? a()가 먼저 실행되면 "A!"가 팝업됩니다. 이때 newFunc는 a의 반환 값을 받아들입니다. 이때 newFunc는 다시 newFunc가 실행될 때 "B"가 됩니다. "가 뜹니다. !”
3. JavaScript의 범위
JavaScript의 범위는 매우 특별합니다. 다른 언어처럼 블록(예: 루프)이 아닌 함수를 기반으로 합니다. 다음 예를 살펴보세요.
var a = 1; function f(){var b = 1; return a;}
이때 b의 값을 얻으려고 하면: Firebug에 Alert(b)를 입력하려고 하면 오류가 발생합니다. 팁:
b는 정의되지 않았습니다.
이것을 이해할 수 있는 이유: 현재 있는 프로그래밍 환경이나 창은 유니버스와 같은 최상위 함수이지만 b는 단지 변수일 뿐입니다. 내부 함수는 우주의 작은 행성에 있는 한 지점을 찾기가 어렵기 때문에 이 환경에서는 호출할 수 없습니다. 반대로 이 내부 함수는 변수 a를 호출할 수 있습니다. 왜냐하면 전체에 노출되어 있기 때문입니다. 우주에는 숨을 곳이 없으며, 함수 내부의 자체 행성에 있기 때문에 b 를 호출할 수도 있습니다.
위 예의 경우:
f() 외부에서는 a가 표시되지만 b는 표시되지 않습니다.
f() 내부에서는 a가 표시되고 b도 표시됩니다
조금 더 복잡합니다.
코드 복사 코드는 다음과 같습니다.

var a = 1; c는 이 레이어에도 없습니다.
function f(){
var b = 1;
function n() { //a, b, c는 모두 이 n 함수를 호출할 수 있음을 알 수 있습니다. a, b는 노출되고 c는 자체 내부
var c = 3
}
}

물어보세요. b 함수가 변수 c를 호출할 수 있나요? 아니요, JavaScript의 범위는 함수를 기반으로 한다는 점을 기억하세요. c는 n 안에 있으므로 f에는 표시되지 않습니다.

공식적으로 폐쇄에 관해 이야기하기 시작하세요.

먼저 이 사진을 보세요:

G, F, N이 각각 세 가지 수준의 함수를 나타내고, 수준은 그림과 같고, a, b, c는 각각 변수라고 가정합니다. 위에서 언급한 범위를 바탕으로 다음과 같은 결론을 내렸습니다.

  1. A 지점에 있다면 b를 참조할 수 없습니다. b는 여러분에게 보이지 않기 때문입니다.
  2. c만이 b를 참조할 수 있습니다

클로저의 역설적인 점은 다음과 같은 일이 발생한다는 것입니다.

N이 F의 한계를 돌파합니다! 와 같은 층에 갔어요! 함수는 정의된 환경만 인식하기 때문에 ( 실행될 때가 아니라 매우 중요합니다 ), 이때 N의 c는 여전히 b에 액세스할 수 있습니다! 아직도 b에 접근할 수 없습니다!

그런데 이것이 어떻게 달성됩니까?
클로저 1:

코드 복사 코드는 다음과 같습니다.

function f( ){
var b = "b";
return function(){ // 이름이 없는 함수이므로 익명 함수입니다.
return b; 🎜>

반환된 함수는 상위 함수의 변수 b에 액세스할 수 있다는 점에 유의하세요.
이때 b의 값을 얻으려면 당연히 정의되지 않습니다.
하지만 그렇게 하면 this:



코드 복사 코드는 다음과 같습니다. var n = f();
n();


b값을 얻을 수 있습니다! 이때 n 함수는 f 외부에 있고 b는 f 내부에 변수이지만 f 내부에는 내부자가 있고 b의 값이 반환됩니다...
이제 다들 느낌이겠죠
클로저 2:



function f(){
var b = "b";
n = function(){
return b;
}
}


어떻게 될까요? 이때 f가 호출된다면? 그런 다음 n의 전역 범위 함수가 생성되지만 f의 내부에 액세스할 수 있으며 여전히 위와 유사한 b 값을 반환할 수 있습니다!
클로저 3:
클로저를 사용하여 함수의 매개변수에 액세스할 수도 있습니다.



코드 복사 코드 function f(arg) {
var n = function(){
return arg
}
arg
return n; ;
}


사용하는 경우:


코드 복사 코드는 다음과 같습니다. : var m = f(123)
m()


결과는 124입니다.
f에서 반환된 익명 함수는 처음에는 n으로, 그 다음에는 외부 m으로 두 번 손이 바뀌었지만 정의되었을 때 본질은 변경되지 않았습니다.
클로저 4:
코드 복사 코드는 다음과 같습니다.

var getValue, setValue;
function() {
var secret = 0;
getValue = function(){
return secret
}; secret = v
};
})


실행:


코드 복사 코드는 다음과 같습니다. getValue()
0
setValue(123)
getValue()
123


No 이것을 설명해야 하는데, 객체지향 언어(예: C#)에 기초가 있다면 여기서 getValue와 setValue는 객체의 속성 접근자와 비슷하며, 이 두 접근자를 통해 값을 할당하고 가져올 수 있습니다. 하지만 내용에 액세스하지는 마세요
사실 책에는 클로저에 대한 몇 가지 예가 있지만 위의 네 가지 원칙만으로도 충분합니다. JavaScript 고급 독자에게 클로저에 대한 더 깊은 이해를 제공하는 출발점이 되기를 바랍니다

관련 라벨:
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
최신 이슈
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿