Javascript의 악명 높은 루프 문제 재검토
Javascript의 악명 높은 루프 문제는 계속해서 개발자를 당황하게 합니다. 다음 코드 조각을 고려하세요.
function addLinks () { for (var i=0, link; i<5; i++) { link = document.createElement("a"); link.innerHTML = "Link " + i; link.onclick = function () { alert(i); }; document.body.appendChild(link); } }
이 코드는 현재 링크 ID를 표시하는 onClick 이벤트가 포함된 5개의 링크를 생성하기 위한 것입니다. 그러나 이러한 링크를 클릭하면 모두 "링크 5"가 표시됩니다.
이 문제의 근본 원인은 Javascript의 함수 수준 범위 지정에 있습니다. 루프가 완료되면 i 변수는 값 5를 유지합니다. 이는 Javascript 함수가 어휘 환경에서 닫혀 있기 때문입니다. 즉, 주변 범위에 정의된 변수에 액세스할 수 있습니다.
이 문제에 대한 해결 방법 각 반복에 대해 i의 현재 값을 캡처하는 클로저를 도입하는 것입니다.
function addLinks () { for (var i=0, link; i<5; i++) { link = document.createElement("a"); link.innerHTML = "Link " + i; link.onclick = function (num) { return function () { alert(num); }; }(i); document.body.appendChild(link); } }
이 코드에서는 각 링크에 대해 새 함수 개체가 생성됩니다. 여기에는 자체 범위와 i의 현재 값이 할당되는 지역 변수 num이 있습니다. 내부 함수가 실행되면 클로저의 num 변수를 참조하여 루프에 할당된 올바른 값을 유지합니다.
이 접근 방식은 효과적이지만 새 함수가 생성되면 성능 저하가 발생합니다. 모든 이벤트 리스너에 대해. 보다 효율적인 대안은 데이터 저장을 위해 DOM 노드 자체를 사용하는 것입니다.
function linkListener() { alert(this.i); } function addLinks () { for(var i = 0; i < 5; ++i) { var link = document.createElement('a'); link.appendChild(document.createTextNode('Link ' + i)); link.i = i; link.onclick = linkListener; document.body.appendChild(link); } }
i 값을 DOM 노드에 직접 저장함으로써 클로저가 필요하지 않으므로 코드 효율성이 향상됩니다.
위 내용은 Javascript 루프로 인해 이벤트 처리기에서 예기치 않은 동작이 발생하는 이유는 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!