programing

JavaScript 폐쇄 vs. 익명 함수

goodsources 2022. 12. 19. 21:47
반응형

JavaScript 폐쇄 vs. 익명 함수

내 친구와 나는 현재 JS에서 무엇이 폐쇄되고 무엇이 폐쇄되지 않는지에 대해 논의하고 있다.우리가 제대로 이해하고 있는지 확인하고 싶을 뿐입니다.

예를 들어 보겠습니다.카운트 루프가 있어 지연된 콘솔의 카운터 변수를 출력하려고 합니다. 때문에 는 '우리'를 사용합니다.setTimeout 닫힘을 사용하여 카운터 변수의 값을 캡처하여 N 곱하기 N 값을 인쇄하지 않도록 합니다.

폐쇄 또는 폐쇄에 가까운 것이 없는 잘못된 해결책은 다음과 같습니다.

for(var i = 0; i < 10; i++) {
    setTimeout(function() {
        console.log(i);
    }, 1000);
}

는 물론 .i루프 후에, 즉 10이 됩니다.

그래서 그의 시도는 다음과 같았다.

for(var i = 0; i < 10; i++) {
    (function(){
        var i2 = i;
        setTimeout(function(){
            console.log(i2);
        }, 1000)
    })();
}

예상대로 0 ~9 를 인쇄합니다.

난 그에게 폐쇄를 이용해서 잡으려는 게 아니라고 말했다.i그렇다고 우기고 있어요포루프 본체를 다른 루프 안에 넣어 클로저를 사용하지 않는다는 것을 증명했습니다.setTimeout에 할당)setTimeout 10 10을 다시 10×10을 인쇄하다.가 그의 a the the the the the the the 。var루프 후에 실행하고, 10 곱하기 10도 인쇄합니다.그래서 내 주장은 가 의 가치를 제대로 파악하지 못하여 그의 버전을 폐쇄적이지 않게 만든다는 이다.

내가 시도한 것은:

for(var i = 0; i < 10; i++) {
    setTimeout((function(i2){
        return function() {
            console.log(i2);
        }
    })(i), 1000);
}

제가 캡쳐를 해봤습니다.i(이름부여))i2다른 기능을 반환하여 이 기능을 전달합니다.제 경우 set Timeout으로 전달된 함수는 실제로 캡처됩니다.

이제 누가 폐쇄를 사용하고 누가 사용하지 않는가?

두 솔루션 모두 콘솔에서 0 ~9 의 인쇄가 지연되기 때문에 원래의 문제를 해결하지만, 이 두 솔루션 중 어떤 솔루션이 폐쇄를 사용하는지 알고 싶습니다.

편집자 메모:JavaScript의 모든 함수는 이 게시물에서 설명한 바와 같이 폐쇄입니다.그러나 우리는 이론적인 관점에서 흥미로운 기능의 하위 집합을 식별하는 데에만 관심이 있다.따라서 closure라는 단어에 대한 참조는 달리 명시되지 않는 한 이 기능의 서브셋을 참조합니다.

폐쇄에 대한 간단한 설명:

  1. 함수를 받아들이다.F라고 부르자.
  2. F의 모든 변수를 나열합니다.
  3. 변수에는 다음 두 가지 유형이 있습니다.
    1. 로컬 변수(바운드 변수)
    2. 로컬이 아닌 변수(자유 변수)
  4. F에 자유 변수가 없으면 폐쇄일 수 없습니다.
  5. F에 자유변수(F의 부모 스코프에서 정의)가 있는 경우:
    1. 자유 변수가 바인딩된 F의 부모 스코프는 1개뿐이어야 합니다.
    2. 부모 스코프 외부에서 F참조되면 해당 자유 변수의 닫힘이 됩니다.
    3. 자유 변수를 폐쇄 F의 상승 값이라고 합니다.

이제 누가 폐쇄를 사용하고 누가 사용하지 않는지 알아보겠습니다(설명을 위해 함수 이름을 붙였습니다).

케이스 1: 친구의 프로그램

for (var i = 0; i < 10; i++) {
    (function f() {
        var i2 = i;
        setTimeout(function g() {
            console.log(i2);
        }, 1000);
    })();
}

에서는 두 기능이 .f ★★★★★★★★★★★★★★★★★」g폐쇄 여부를 확인합니다.

★★★의 f:

  1. 변수를 나열합니다.
    1. i2로컬 변수입니다.
    2. i자유 변수입니다.
    3. setTimeout자유 변수입니다.
    4. g로컬 변수입니다.
    5. console자유 변수입니다.
  2. 각 자유 변수가 바인딩되어 있는 부모 범위를 찾습니다.
    1. i글로벌 스코프에 바인드 되어 있습니다.
    2. setTimeout글로벌 스코프에 바인드 되어 있습니다.
    3. console글로벌 스코프에 바인드 되어 있습니다.
  3. 기능은 어느 범위에서 참조됩니까?글로벌 스코프
    1. 때문에, 「 」는 할 수 없습니다.i에 의해 닫히지 않는다.f.
    2. 때문에, 「 」는 할 수 없습니다.setTimeout에 의해 닫히지 않는다.f.
    3. 때문에, 「 」는 할 수 없습니다.console에 의해 닫히지 않는다.f.

, 함수는 다음과 같습니다.f힘이아아 아아아다다

★★★의 g:

  1. 변수를 나열합니다.
    1. console자유 변수입니다.
    2. i2자유 변수입니다.
  2. 각 자유 변수가 바인딩되어 있는 부모 범위를 찾습니다.
    1. console글로벌 스코프에 바인드 되어 있습니다.
    2. i2의 범위에 속박되어 있다f.
  3. 기능은 어느 범위에서 참조됩니까?의 범위.
    1. 때문에, 「 」는 할 수 없습니다.console에 의해 닫히지 않는다.g.
    2. 때문에, 「 」는 할 수 없습니다.i2에 의해 닫힙니다.g.

, 함수는 다음과 같습니다.g는 자유변수인 입니다.i2)g내부로부터 참조되는 경우)setTimeout.

좋아: 친구가 클로저를 사용하고 있습니다.내부 함수는 폐쇄입니다.

케이스 2: 프로그램

for (var i = 0; i < 10; i++) {
    setTimeout((function f(i2) {
        return function g() {
            console.log(i2);
        };
    })(i), 1000);
}

에서는 두 기능이 .f ★★★★★★★★★★★★★★★★★」g폐쇄 여부를 확인합니다.

★★★의 f:

  1. 변수를 나열합니다.
    1. i2로컬 변수입니다.
    2. g로컬 변수입니다.
    3. console자유 변수입니다.
  2. 각 자유 변수가 바인딩되어 있는 부모 범위를 찾습니다.
    1. console글로벌 스코프에 바인드 되어 있습니다.
  3. 기능은 어느 범위에서 참조됩니까?글로벌 스코프
    1. 때문에, 「 」는 할 수 없습니다.console에 의해 닫히지 않는다.f.

, 함수는 다음과 같습니다.f힘이아아 아아아다다

★★★의 g:

  1. 변수를 나열합니다.
    1. console자유 변수입니다.
    2. i2자유 변수입니다.
  2. 각 자유 변수가 바인딩되어 있는 부모 범위를 찾습니다.
    1. console글로벌 스코프에 바인드 되어 있습니다.
    2. i2의 범위에 속박되어 있다f.
  3. 기능은 어느 범위에서 참조됩니까?의 범위.
    1. 때문에, 「 」는 할 수 없습니다.console에 의해 닫히지 않는다.g.
    2. 때문에, 「 」는 할 수 없습니다.i2에 의해 닫힙니다.g.

, 함수는 다음과 같습니다.g는 자유변수인 입니다.i2)g내부로부터 참조되는 경우)setTimeout.

좋습니다.폐쇄를 사용하고 있습니다.내부 함수는 폐쇄입니다.

당신과 당신 친구 둘 다 클로저를 사용하고 있군요.다투지 마세요.내가 폐쇄의 개념과 둘을 위한 식별 방법을 지웠길 바란다.

편집: 모든 기능이 폐쇄되는 이유에 대한 간단한 설명(credit @Peter):

먼저 다음 프로그램(컨트롤)에 대해 살펴보겠습니다.

lexicalScope();

function lexicalScope() {
    var message = "This is the control. You should be able to see this message being alerted.";

    regularFunction();

    function regularFunction() {
        alert(eval("message"));
    }
}

  1. 다 알고 lexicalScope ★★★★★★★★★★★★★★★★★」regularFunction위 정의의 폐쇄가 아닙니다.
  2. 우리가 기대하는 프로그램을 실행할 때 message(경보를 받다 regularFunction폐쇄는 아닙니다(즉, 상위 범위의 모든 변수에 액세스할 수 있습니다).message를 참조해 주세요.
  3. 프로그램을 실행할 때 다음을 관찰합니다.message정말로 경계하고 있다.

다음으로 다음 프로그램(대안)에 대해 살펴보겠습니다.

var closureFunction = lexicalScope();

closureFunction();

function lexicalScope() {
    var message = "This is the alternative. If you see this message being alerted then in means that every function in JavaScript is a closure.";

    return function closureFunction() {
        alert(eval("message"));
    };
}

  1. 가 아는 것은 오직 한 가지뿐입니다.closureFunction는 위의 정의에서 종료된 것입니다.
  2. 우리가 기대하는 프로그램을 실행할 때 message주의할 필요가 없다 closureFunction는 닫힘입니다(즉, 함수가 생성될 때에만 로컬이 아닌 모든 변수에 액세스할 수 있습니다( 답변 참조). 여기에는 다음이 포함되지 않습니다.message를 참조해 주세요.
  3. 프로그램을 실행할 때 다음을 관찰합니다.message실제로 경고를 받고 있습니다.

여기서 무엇을 추론할 수 있을까요?

  1. JavaScript 인터프리터는 폐쇄를 다른 함수와 다르게 취급하지 않습니다.
  2. 모든 기능은 스코프 체인을 함께 운반합니다.폐쇄에는 별도의 참조 환경이 없습니다.
  3. 닫힘은 다른 모든 함수와 같습니다.이것이 흥미로운 경우이기 때문에 우리는 단지 그들이 속한 범위 밖에서 언급될 때 폐쇄라고 부른다.

★★★★★★에 의하면closure★★★★

"closure"는 표현식(일반적으로 표현식을 "닫는" 환경과 함께 자유 변수를 가질 수 있는 함수)입니다.

사용하고 있습니다.closure함수 외부에 정의된 변수를 사용하는 함수를 정의하는 경우.(변수를 자유변수라고 부릅니다).
'아예'를 사용합니다.closure( 째 ( ( ( ( ( )

한마디로 Javascript Closures를 사용하면 함수가 어휘-부모 함수로 선언변수에 액세스할있습니다.

좀 더 자세한 설명을 봅시다.닫힘을 이해하려면 JavaScript가 변수의 범위를 지정하는 방법을 이해하는 것이 중요합니다.

범위

JavaScript에서 스코프는 함수와 함께 정의됩니다.모든 함수는 새로운 스코프를 정의합니다.

다음 예를 생각해 보겠습니다.

function f()
{//begin of scope f
  var foo='hello'; //foo is declared in scope f
  for(var i=0;i<2;i++){//i is declared in scope f
     //the for loop is not a function, therefore we are still in scope f
     var bar = 'Am I accessible?';//bar is declared in scope f
     console.log(foo);
  }
  console.log(i);
  console.log(bar);
}//end of scope f

호출, 인쇄

hello
hello
2
Am I Accessible?

이번에는 함수가 요?g 함수로 f.

function f()
{//begin of scope f
  function g()
  {//being of scope g
    /*...*/
  }//end of scope g
  /*...*/
}//end of scope f

하겠습니다.f어휘의 모체g와 같이 스코프는는 2가지입니다.스코프f 스코프 및 andg.

그러나 한 범위는 다른 범위 내에 있으므로 하위 기능의 범위가 상위 기능의 범위 중 일부입니까?상위 함수의 범위에서 선언된 변수는 어떻게 됩니까? 하위 함수의 범위에서 해당 변수에 액세스할 수 있습니까?그게 바로 폐쇄가 필요한 부분이야.

폐쇄

에서는 함수 JavaScript가 됩니다.g "에서 할 수 .g 함수의 에서 선언된 .f.

다음 사항을 고려하십시오.

function f()//lexical parent function
{//begin of scope f
  var foo='hello'; //foo declared in scope f
  function g()
  {//being of scope g
    var bar='bla'; //bar declared in scope g
    console.log(foo);
  }//end of scope g
  g();
  console.log(bar);
}//end of scope f

호출, 인쇄

hello
undefined

줄 한번 console.log(foo);에서 우리는 안에 g 변수 하겠습니다.fooscope에 되어 .f, 사전에 한 바와 , 할 수 있습니다.「 」 、 「 」 、 「 」 、 「 」 、 「 」g의 어휘의 부모입니다.f.그러므로hello인쇄되어 있습니다.
이번에는 줄 console.log(bar);에서 우리는 안에 f 변수 하겠습니다.barscope에 되어 .gbar되지 않은 입니다.g의 부모가 .f 때문에bar되어 있지 않다

실제로 어휘적 "대부모" 함수의 범위에서 선언된 변수에도 액세스할 수 있습니다. 때문에 만약 therefore function function function function면면면면면면면면면 thereforeh에 .g

function f()
{//begin of scope f
  function g()
  {//being of scope g
    function h()
    {//being of scope h
      /*...*/
    }//end of scope h
    /*...*/
  }//end of scope g
  /*...*/
}//end of scope f

h 범위 된 모든 수 .h,g , , , , 입니다.f이 작업은 폐쇄로 이루어집니다.JavaScript closures에서는 어휘적 부모함수, 어휘적 대부모함수, 어휘적 대부모함수 등에서 선언된 변수에 액세스할 수 있습니다.이것은 스코프 체인으로 볼 수 있습니다. scope of current function -> scope of lexical parent function -> scope of lexical grand parent function -> ... 어휘적 부모가 없는 마지막 부모 함수까지.

window 객체

사실 체인은 마지막 부모 기능에서 멈추지 않습니다.하나 더 특별한 범위가 있습니다. 글로벌 범위입니다.함수로 선언되지 않은 모든 변수는 글로벌 범위에서 선언된 것으로 간주됩니다.글로벌 스코프에는 두 가지 전문성이 있습니다.

  • 글로벌 스코프에서 선언된 모든 변수에 어디서나 액세스할 수 있습니다.
  • 글로벌 스코프에서 선언된 변수는 다음 속성에 대응합니다.window★★★★★★ 。

변수를 두 .foo에서는, 을 함수로 하지 않는 것, 「」을 .foo를 선택합니다.

두 시도 모두 폐쇄를 사용합니다.

이제 자세한 설명을 읽었으므로 두 솔루션 모두 폐쇄를 사용하고 있는 것이 분명합니다.하지만 만약을 위해, 증거를 만들어보자.

새로운 프로그래밍 언어 JavaScript-No-Closure를 만듭니다.이름에서 알 수 있듯이, JavaScript-No-Closure는 Closures를 지원하지 않는다는 점을 제외하고는 JavaScript와 동일합니다.

바꿔 말하면

var foo = 'hello';
function f(){console.log(foo)};
f();
//JavaScript-No-Closure prints undefined
//JavaSript prints hello

자, 그럼 JavaScript-No-Closure를 사용한 첫 번째 솔루션이 어떻게 되는지 살펴보겠습니다.

for(var i = 0; i < 10; i++) {
  (function(){
    var i2 = i;
    setTimeout(function(){
        console.log(i2); //i2 is undefined in JavaScript-No-Closure 
    }, 1000)
  })();
}

인쇄가 .undefinedJavaScript-No-Closure™ 10인치

따라서 첫 번째 솔루션은 폐쇄를 사용합니다.

두 번째 솔루션에 대해 살펴보겠습니다.

for(var i = 0; i < 10; i++) {
  setTimeout((function(i2){
    return function() {
        console.log(i2); //i2 is undefined in JavaScript-No-Closure
    }
  })(i), 1000);
}

인쇄가 .undefinedJavaScript-No-Closure™ 10인치

두 솔루션 모두 폐쇄를 사용합니다.

편집: 이 3개의 코드 스니펫은 글로벌 범위에서 정의되어 있지 않은 것으로 간주됩니다. 않은 변수 " " " "foo ★★★★★★★★★★★★★★★★★」i에 속박되어 있다.window이기 때문에, 「접근할 수 있다」를 통해서 할 수 .windowJavaScript' JavaScript-No-Closure' 입니다.

누가 이걸 설명하는 게 마음에 안 들어

폐쇄를 이해하는 열쇠는 폐쇄가 없는 JS를 이해하는 것이다.

닫힘이 없으면 오류가 발생합니다.

function outerFunc(){
    var outerVar = 'an outerFunc var';
    return function(){
        alert(outerVar);
    }
}

outerFunc()(); //returns inner function and fires it

일단 outerFunc가 가상의 폐쇄 비활성 버전의 JavaScript로 돌아오면 outerVar에 대한 참조는 가비지가 수집되어 내부 펑크가 참조할 수 있도록 아무것도 남지 않게 됩니다.

폐쇄는 본질적으로 내부 함수가 외부 함수의 변수를 참조할 때 이러한 변수들이 존재할 수 있도록 하는 특별한 규칙입니다.닫힘을 사용하면 외부 기능이 완료된 후에도 참조된 변수가 유지되거나, 점을 기억하는 데 도움이 되는 경우 '닫힘' 상태가 유지됩니다.

폐쇄를 사용하더라도 로컬을 참조하는 내부 펑크가 없는 함수에서 로컬 변수의 수명 주기는 폐쇄가 없는 버전에서와 동일하게 작동합니다.그 기능이 끝나면, 지역 주민들은 쓰레기를 수거한다.

내부 펑크에서 외부 변수에 대한 참조를 얻으면 참조된 변수의 가비지 수집에 도어잼이 들어가는 것과 같습니다.

폐쇄를 보다 정확하게 볼 수 있는 방법은 내부 함수가 기본적으로 내부 범위를 자체 범위 범위로 사용하는 것입니다.

그러나 참조되는 컨텍스트는 실제로는 스냅샷과 같은 것이 아니라 지속적입니다.반환된 내부 함수가 계속 증가하고 외부 함수의 로컬 변수가 기록되는 것을 반복하면 더 높은 값을 계속 경고합니다.

function outerFunc(){
    var incrementMe = 0;
    return function(){ incrementMe++; console.log(incrementMe); }
}
var inc = outerFunc();
inc(); //logs 1
inc(); //logs 2

둘 다 클로저를 사용하고 있습니다.

Wikipedia의 정의를 다음에 나타냅니다.

컴퓨터 과학에서 클로저(어휘적 클로저 또는 함수 클로저)는 참조 환경과 함께 함수에 대한 함수 또는 참조입니다. 즉, 해당 함수의 각 비국소 변수(자유 변수라고도 함)에 대한 참조를 저장하는 표입니다.일반 함수 포인터와 달리 닫힘을 사용하면 함수가 직접 어휘 범위 밖에서 호출된 경우에도 이러한 비로컬 변수에 액세스할 수 있습니다.

는 분명히 하고 있습니다.i 경우 i2.

가 통과하다.i(콜 사이트의 범위 내) 어나니머스 함수에 인수로서 사용됩니다. 함수는 , 이는 같은 하는 다른 합니다.i2 함수 어나니머스 함수이기 i2로컬이 아니므로 폐쇄가 생성됩니다.

당신과 당신의 친구 모두 폐쇄를 사용합니다.

폐쇄는 기능과 그 기능이 생성된 환경의 두 가지를 결합한 특수한 객체입니다.환경은 폐쇄가 생성되었을 때 적용 범위에 있던 모든 로컬 변수로 구성됩니다.

MDN: https://developer.mozilla.org/en-US/docs/JavaScript/Guide/Closures

함수 ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★」function(){ console.log(i2); } 함수의 inside anonymous 함수의 정의 완료function(){ var i2 = i; ... 로컬 변수를 읽고 쓸 수 있습니다.

함수 드드 in in in in in in in in in infunction(){ console.log(i2); }.function(i2){ return ...로컬 밸류(이 경우 파라미터로 지정)를 읽고 쓸 수 있습니다.

모두 함수 " " " "function(){ console.log(i2); }그 후 로 넘어갔다.setTimeout.

또 다른 동등한 기능(단, 메모리 사용률이 낮다)은 다음과 같습니다.

function fGenerator(i2){
    return function(){
        console.log(i2);
    }
}
for(var i = 0; i < 10; i++) {
    setTimeout(fGenerator(i), 1000);
}

클로즈

닫힘은 함수도 식도 아닙니다.기능 범위 밖에서 사용된 변수에서 일종의 '스냅샷'으로 보고 기능 내에서 사용해야 합니다.문법적으로, '변수의 닫힘을 취하라'라고 말해야 한다.

다시 말해, 닫힘은 함수가 의존하는 변수의 관련 컨텍스트의 복사본입니다.

다시 한 번(naff):닫힘은 매개 변수로 전달되지 않는 변수에 액세스할 수 있는 것입니다.

이러한 기능 개념은 사용하는 프로그래밍 언어/환경에 따라 크게 달라지는 점에 유의하십시오.JavaScript에서 닫힘은 어휘 범위(대부분의 C 언어에서 해당)에 따라 달라집니다.

따라서 함수를 반환하는 것은 대부분 익명/이름 없는 함수를 반환하는 것입니다.함수 액세스 변수가 매개 변수로 전달되지 않고 해당(레거시) 범위 내에 있으면 닫힙니다.

그럼, 당신의 예에 대해서:

// 1
for(var i = 0; i < 10; i++) {
    setTimeout(function() {
        console.log(i); // closure, only when loop finishes within 1000 ms,
    }, 1000);           // i = 10 for all functions
}
// 2
for(var i = 0; i < 10; i++) {
    (function(){
        var i2 = i; // closure of i (lexical scope: for-loop)
        setTimeout(function(){
            console.log(i2); // closure of i2 (lexical scope:outer function)
        }, 1000)
    })();
}
// 3
for(var i = 0; i < 10; i++) {
    setTimeout((function(i2){
        return function() {
            console.log(i2); // closure of i2 (outer scope)

        }
    })(i), 1000); // param access i (no closure)
}

모두 클로저를 사용하고 있습니다.처형 지점과 폐쇄 지점을 혼동하지 마십시오.잘못된 순간에 폐쇄의 '스냅샷'을 찍으면 예기치 않은 값이 될 수 있지만 확실히 폐쇄됩니다!

양쪽 모두에 대해 생각해 봅시다.

(function(){
    var i2 = i;
    setTimeout(function(){
        console.log(i2);
    }, 1000)
})();

합니다.setTimeout()아!" " " 의 값.i.i2첫 번째, 즉시 실행되기 때문에 동작합니다.

setTimeout((function(i2){
    return function() {
        console.log(i2);
    }
})(i), 1000);

에 의해, 현재의 은 「」입니다.이 경우 현재 값은i되어 있다i2; 이 접근법에서는 값을 유지하기 위해 즉시 실행도 사용합니다.

중요한

는 두 는 ""으로 .이치노setTimeout(), 함수는 '이러다'를 호출한다.setTimeout()그 자체입니다.

모두 다른 안에 래핑합니다.setTimeout()두 번째 접근법만 폐쇄를 사용한다는 걸 증명하는 건 아닙니다.음음 츠키

결론

두 방법 모두 폐쇄를 사용하기 때문에 개인적인 취향으로 귀결됩니다. 두 번째 방법은 주위를 "이동"하거나 일반화하는 것이 더 쉽습니다.

JS에서 클로징이 무엇이고 어떻게 작동하는지 상기시키기 위해 이 글을 썼습니다.

닫힘은 호출된 범위가 아니라 선언된 범위를 사용하는 함수입니다.JavaScript에서는 모든 함수가 다음과 같이 동작합니다.스코프에서 변수 값을 가리키는 함수가 있는 한 변수 값은 유지됩니다.규칙의 예외는 'this'입니다.이거는 함수가 호출될 때 함수가 안에 있는 개체를 나타냅니다.

var z = 1;
function x(){
    var z = 2; 
    y(function(){
      alert(z);
    });
}
function y(f){
    var z = 3;
    f();
}
x(); //alerts '2' 

자세히 살펴본 결과, 두 분 모두 클로저를 사용하고 있는 것 같습니다.

의 경우는 ★★★★★★★★★★★★★★★★★★★★★★★★★★★★.i1 및 anonymous function 1 내에서 .i2.서 '2'는 어나니머스 함수2로 액세스 됩니다.console.log재합니니다다

, 「」에 액세스 하고 .i2. 여기서 "는 어나니머스 함수입니다.console.log존재합니다.를 추가합니다.debugger;console.log'범위 변수'라고 합니다.

이치노 함수가 되고 다시 됩니다.f에 that that that that that thati 다른 아, 아, 아!

i=100;

f=function(i){return function(){return ++i}}(0);
alert([f,f(),f(),f(),f(),f(),f(),f(),f(),f(),f()].join('\n\n'));

f=function(i){return new Function('return ++i')}(0);        /*  function declarations ~= expressions! */
alert([f,f(),f(),f(),f(),f(),f(),f(),f(),f(),f()].join('\n\n'));

가함수가함수 가함수 가함수 가함수 가함수 가 닫힙니다.
이합니다.f

for(var i = 0; i < 10; i++) {
    setTimeout( new Function('console.log('+i+')'),  1000 );
}

또는 좀 더 명확하게 말하면:

for(var i = 0; i < 10; i++) {
    console.log(    f = new Function( 'console.log('+i+')' )    );
    setTimeout( f,  1000 );
}

.ffunction(){ console.log(9) } 0인쇄되어 있습니다.

주의! 폐쇄 개념은 초등 프로그래밍의 본질에서 강압적으로 주의를 분산시킬 수 있습니다.

for(var i = 0; i < 10; i++) {     setTimeout( 'console.log('+i+')',  1000 );      }

x-refs:
자바스크립트?
Closures Javascript ★★★★★★★★★★★★★★★★★★★★
a Function(JS; 기능 내에서의 기능 )
Javascript?
및 변수 혼돈 Javascript

폐업에 대한 제 예시와 설명을 공유하고자 합니다.python의 예시와 스택 상태를 나타내는 2개의 그림을 작성했습니다.

def maker(a, b, n):
    margin_top = 2
    padding = 4
    def message(msg):
        print('\n’ * margin_top, a * n, 
            ' ‘ * padding, msg, ' ‘ * padding, b * n)
    return message

f = maker('*', '#', 5)
g = maker('', '♥’, 3)
…
f('hello')
g(‘good bye!')

이 코드의 출력은 다음과 같습니다.

*****      hello      #####

      good bye!    ♥♥♥

다음은 스택과 함수 객체에 부착된 닫힘을 보여주는 두 가지 그림입니다.

제조사에서 기능이 반환될 때

함수가 나중에 호출될 때

함수가 파라미터 또는 비로컬 변수를 통해 호출되면 코드에는 a, b, n뿐만 아니라 margin_top, padding 등의 로컬 변수 바인딩이 필요합니다.기능 코드가 확실히 기능하기 위해서는 오래 전에 없어진 메이커 기능의 스택 프레임에 액세스 할 수 있어야 합니다.이것은 함수 메시지 오브젝트와 함께 클로저에 백업되어 있습니다.

언급URL : https://stackoverflow.com/questions/12930272/javascript-closures-vs-anonymous-functions

반응형