21

JavaScript에서 동적으로 생성 된 "a"태그의 onclick 이벤트에 함수를 할당하려고했습니다. 모든 태그는 다음과 같이 루프로 작성됩니다.루프 (다른 함수를 반환)의 함수는 어떻게 작동합니까?

for (var i = 0; i < 4; i++) 
{ 
    var a = document.createElement("a"); 
    a.onclick = function() { alert(i) }; 
    document.getElementById("foo").appendChild(a); 
} 

네 개의 링크 모두에 대한 경고 값은 항상 "4"입니다. 꽤 분명해. 인터넷 검색을 할 때 나는 다음과 같은 코드 조각을 보여줍니다 게시물 건너 온 :

a.onclick = (function(p, d) { 
return function(){ show_photo(p, d) } 
})(path, description); 

내 요구를 조정할 관리 및 경고 (전) 일이 제대로 작동있어하지만 누군가가 정확하게 설명 할 수 있다면 감사 할 것 위 코드가하는 일.

+0

안녕 :

나는 폐쇄 (그리고 curry의 아주 기본적인 개념)를 설명하기 위해 다음 코드를 사용하여, 나는 간단한 예는 개념을 얻을 쉽게 만들 수 있다고 생각 경고 "4"? "2"가 아니어야합니까? 감사. – Tarik

+0

for (var i = 0; i <3; i ++)는 끝에서 i == 4를 남깁니다. –

+1

아니요, 3을 그대로 남겨 둡니다. –

답변

45

: 문제는 함수를 반환하는 함수를 사용하는 것입니다.

기본적으로 함수를 중첩 할 때 클로저가 만들어 지므로 내부 함수는 부모 함수가 이미 실행 된 후에도 내부 함수에서 변수를 참조 할 수 있습니다.

클릭 이벤트가 실행될 때 핸들러는 i 변수가 가지고있는 마지막 값을 참조합니다. 그 변수는 클로저에 저장되어 있기 때문입니다.당신이 눈치

, 다른 함수를 인수로 i 변수를 수용하기 위해 클릭 핸들러 함수를 포장하고, 반환하여이 예상대로 작동합니다 (기본적으로 다른 폐쇄를 만들 수) :

for (var i = 0; i < 4; i++) { 
    var a = document.createElement("a"); 
    a.onclick = (function(j) { // a closure is created 
    return function() { 
     alert(j); 
    } 
    }(i)); 
    document.getElementById("foo").appendChild(a); 
} 

을 iterate, 실제로 4 개의 함수를 생성하고, 각 함수는 (i을 전달하여) 생성되었을 때 i에 대한 참조를 저장하고,이 값은 외부 클로저에 저장되고 click 이벤트가 발생하면 내부 함수가 실행됩니다. 왜 당신이 말해 줄 수,

// a function that generates functions to add two numbers 
function addGenerator (x) { // closure that stores the first number 
    return function (y){ // make the addition 
    return x + y; 
    }; 
} 

var plusOne = addGenerator(1), // create two number adding functions 
    addFive = addGenerator(5); 

alert(addFive(10)); // 15 
alert(plusOne(10)); // 11 
+3

테일러, 나는 너에게 행복하다, 내가 끝내도록 내버려 두 겠지만,이 포스트는 항상 최고의 시간이다. – Tarik

+0

당신이 42k 점을 갖고 있어도 당연 하지요 :) –

+4

어느 날, 사람들은 내가 가진 것처럼 카니 예 웨스트에 대해 잊어 버렸을 것이고, 그를 언급하는 모든 밈은 무례하고 조금 이상해질 것입니다. – RandomInsano

10

너무 자세히 설명하지 않고이 작업은 즉시 실행되는 함수에 래핑하여 인스턴스 변수의 복사본을 생성하고 요소가 클릭 될 때 실행되는 함수로 다시 전달합니다. 이 같은 그것의

생각한다

function() { alert(i); } // Will expose the latest value of i 
(function(I) { return function() { alert(I); }; })(i); // Will pass the current 
                 // value of i and return 
                 // a function that exposes 
                 // i at that time 

그래서 루프의 각 반복하는 동안 당신이 실제로 실행 변수의 현재 값으로 기능을 반환하는 함수입니다.

, 당신은 당신이로 시각화 할 수있는 4 개 별도의 기능을 만드는 루프 4 앵커을 상상하면 ...

function() { alert(0); }; 
function() { alert(1); }; 
function() { alert(2); }; 
function() { alert(3); }; 

내가 자바 스크립트와 범위와 폐쇄를 조사 고려할 경우와 같이 이 길로 내려 가면 예기치 않은 행동으로 막대한 문제가 발생할 수있는 상황을 정확히 이해하지 못합니다.

onclick 이벤트가 트리거되면, 익명 함수 호출과 루프에 사용 된 동일한 변수 i를 나타내며 그 제

의 해결책 i의 최종 값을 유지한다

+0

설명 주셔서 감사합니다. 그건 좋은 해킹 - 또는 자바 스크립트에서 일을하는 방법입니까? – Amarghosh

2

closure이 만들어집니다, 당신은 클릭 처리기에 기능을 할당 할 때

a.onclick = (function(k) {return function() { alert(k); }; })(i); 
관련 문제