질문
코드A
function fun(n,o){ console.log(o); return { fun:function(m){//[2] return fun(m,n);//[1] } } } var a=fun(0); a.fun(1); a.fun(2); a.fun(3); var b=fun(0).fun(1).fun(2).fun(3); var c=fun(0).fun(1); c.fun(2); c.fun(3);
프로그램 출력 찾기
종료 테스트 문제입니다
등가 코드
로 변환return에 의해 반환된 객체의 fun 속성은 새로 생성된 함수 객체에 해당합니다. 이 함수 객체는 클로저 범위를 형성하여 외부 함수의 변수 n과 외부 함수 fun에 액세스할 수 있도록 합니다. fun 함수를 fun 속성과 혼동하면 위 코드를 다음과 같이 수정합니다.
코드B
function _fun_(n,o){ console.log(o); return { fun:function(m){ return _fun_(m,n); } } } var a=_fun_(0);//undefined a.fun(1);//0 a.fun(2);//0 a.fun(3);//0 var b=_fun_(0).fun(1).fun(2).fun(3); //undefined,0,1,2 var c=fun(0).fun(1);//undefined,0, c.fun(2);//1 c.fun(3); //1
그러면 일부 학생들은 왜 이렇게 바뀔 수 있느냐고 묻습니다. [1]의 재미가 코드가 있는 [2]의 재미가 아니라고 어떻게 확신할 수 있습니까? 함수 객체를 가리킵니다. ~
여기서는 JS의 어휘 범위에 대해 이야기합니다. JS 변수 범위는 함수 본문, 즉 함수 본문에 존재하며 변수의 범위는 함수가 실행될 때가 아니라 함수 정의가 선언될 때 결정됩니다.
다음 코드
var name="global"; function foo(){ console.log(name); } function fooOuter1(){ var name="local"; foo(); } fooOuter1();//输出global 而不是local,并且和闭包没有任何关系 function fooOuter2(){ var name="local"; function foo(){ console.log(name); } foo(); } fooOuter2();//输出local 而不是global,在函数声明是name变量作用域就在其外层函数中,嗯嗯就是闭包~<br />
자, 다시 본론으로 돌아가서 함수 선언 정의 단계에서는 [2]에서 익명 함수를 정의하고 선언했는데, 그러면 [1]에서 fun이라는 함수 객체를 참조해야 한다는 것을 알게 되었습니다. 먼저 현재 함수 본문에서 찾으세요. 찾을 수 없으면 외부 함수(이 익명 함수의 래핑 함수)로 이동하여 찾을 수 없습니다. 외부에 함수 래퍼가 없는 걸 발견하고 전역 환경으로 가서 찾으면 어, 드디어 찾았네요... 전역 환경에서 fun 함수 객체로 fun 함수를 지정하고 익명의 클로저에 추가하면 됩니다. 기능. 이제 코드 B가 코드 A와 동일한 이유를 알 수 있습니다~~~
클로저 범위 생성
어휘 분석 후 JS는 반환된 객체의 fun 속성에 해당하는 익명 함수(전역 환경에서 _func_에 액세스하는 함수 내부 변수 n 및 해당 외부 함수)의 클로저인 클로저를 결정합니다. >
_func_가 실행될 때마다 클로저에 있는 변수의 범위 정보가 함수 실행 환경에 전달되어 함수 실행 시 변수 값을 얻을 때 사용됩니다
var a=_fun_(0);//undefined a.fun(1);//0 a.fun(2);//0 a.fun(3);//0
a.fun(1)은 반환된 객체의 fun 메서드를 실행하고 m 1 값을 전달하며 호출은 _fun_(1,0)
을 반환합니다.
따라서 출력은 0, a.fun(2), a.fun(3) 및 a.fun(1)입니다.
var b=_fun_(0).fun(1).fun(2).fun(3);
해당 코드:
var b=_fun_(0);
var b1=b.fun(1);
var b2=b1.fun(2);//[3]
var b3=b2.fun(3);//[4]
처음 두 문장은 위의 출력 undefine,0과 동일합니다. [3]이 호출되면 _fun_ 함수와 외부 함수 변수 n=1을 참조하는 b1 객체에 클로저가 있습니다. 이므로 익명 함수가 수행한 함수 호출은 _fun_(2,1)이고 출력 결과는 1이며 새 개체가 반환됩니다.
[4]가 실행되면 b2 객체에도 _fun_ 함수와 외부 함수 변수 n=2를 참조하는 클로저가 있습니다. _fun_(3,2)가 실행되면 출력 결과는 2
입니다.
var c=fun(0).fun(1);//undefined,0, c.fun(2);//1 c.fun(3); //1