자세한 내용은 ECMA-262-3 5장을 참조하세요.
위 문제를 해결하려면 매우 간단합니다. JavaScript에서는 문장을 괄호() 안에 넣을 수 없기 때문에 중괄호만 사용하면 됩니다. point function 키워드를 구문 분석할 때 파서는 해당 코드를 함수 선언 대신 함수 표현식으로 구문 분석합니다.
일반 함수 실행 시 매개변수를 전달하는 것과 마찬가지로 자체 실행됩니다. 함수 표현식은 이러한 방식으로 매개변수를 전달할 수도 있습니다. 클로저를 직접 참조할 수 있기 때문입니다. 이러한 매개변수가 전달되면 자체 실행 함수 표현식은 잠긴 수신 매개변수를 사용하여 상태를 효과적으로 저장할 수 있습니다.
// 이 때 실제로 값을 얻습니다
// 그러니 상관없습니다 어떤 연결을 클릭하면 최종적으로 표시되는 것은 I am link #10입니다(a 요소가 10개인 경우)
var elems = document.getElementsByTagName('a')
for (var i = 0; i < ; elems.length; i ) {
elems[i].addEventListener('click', function (e) {
e.preventDefault();
alert('나는 링크입니다 #' i);
}, 'false');
}
// 자체 실행 함수 표현식 클로저 내부에 있으므로 사용할 수 있습니다.
// i 값은 잠긴 인덱스로 존재하며 루프에서 실행 종료 후 i의 값은 최종적으로 a의 전체 요소 개수(예: 10)가 되지만
// 클로저 내부의lockedInIndex 값은 실행되었으므로 변경되지 않았습니다
// 따라서 연결 시간을 클릭하면 결과가 정확합니다.
var elems = document.getElementsByTagName('a')
for (var i = 0; i < elems.length; i ) {
(function (lockedInIndex) {
elems[i].addEventListener('click', function (e) {
e.preventDefault();
alert('나는 링크입니다 #'lockedInIndex);
}, 'false' );
})(i);
}
// 핸들러 함수에서 자체 실행 함수 표현식을 사용하여 다음과 같이 적용할 수도 있습니다. // addEventListener 외부 대신
// 하지만 상대적으로 말하면 위 코드가 더 읽기 쉽습니다.
var elems = document.getElementsByTagName('a')
for (var i = 0; i < elems .length; i ) {
elems[i].addEventListener('click', (function (lockedInIndex) {
return function (e) {
e.preventDefault();
alert(' 나는 링크 #'lockedInIndex)
})(i), 'false');
실제로 위 두 예제의 LockedInIndex 변수는 i로 대체될 수도 있습니다. 외부 i와 동일한 기능을 수행하지 않기 때문에 문제가 되지 않습니다. 이 역시 익명 함수 클로저의 힘입니다. .
자체 실행 익명 함수와 즉시 실행 함수 표현식의 차이점
이번 포스팅에서는 항상 자체 실행 함수라고 했는데, 정확히 말하면 자체 실행 익명 함수입니다(Self -익명 함수 실행), 그러나 원본 영어 텍스트 저자는 항상 즉시 호출 함수 표현이라는 이름의 사용을 옹호해 왔습니다. 또한 저자는 설명하기 위해 여러 가지 예를 제시했습니다.
// 자체 실행 함수로 함수가 스스로 실행됩니다. 내부적으로, 재귀적으로
function foo() { foo(); }
// 표시된 이름이 없기 때문에 자체 실행되는 익명 함수입니다.
// 실행하려면args.callee 속성을 사용해야 합니다. 그 자체
var foo = function () {args.callee() }; foo를 다른 것으로 바꾸면 익숙한 자체 실행 익명 함수를 얻게 됩니다.
var foo = function () { foo() }// 어떤 사람들은 이것을 자체 실행 익명 함수라고 부릅니다. (그렇지 않더라도) 자신을 호출하지 않기 때문에 그냥 바로 실행하면 됩니다.
(function () { /* code */ } ());
// 함수 표현식에 레이블 이름을 추가하면 디버깅이 용이해집니다.
// 하지만 이름이 지정되어야 하며 함수는 작동하지 않습니다. 이상 익명입니다
(function foo() { /* code */ } ())
// 즉시 호출 함수 표현식(IIFE)도 자체 실행될 수 있지만 일반적으로 사용되지 않을 수 있습니다
(function () {args.callee(); } ());
(function foo() { foo(); } ())
// 또한 다음 코드는 다음에서 실행됩니다. BlackBerry 5 오류, 명명된 함수 표현식에서 그의 이름이 정의되지 않았기 때문입니다
// 하하, 이상합니다
(function foo() { foo(); } ()); 여기에 있는 몇 가지 예를 통해 모든 사람이 자기 실행이 무엇인지, 즉각 소명이 무엇인지 이해하는 데 도움이 되기를 바랍니다.
참고: Arguments.callee는 ECMAScript 5 엄격 모드에서는 더 이상 사용되지 않으므로 이 모드에서는 사용할 수 없습니다.
최종 내레이션: 모듈 모드
즉시 호출되는 함수 표현식에 대해 이야기할 때 모듈 모드가 익숙하지 않다면 먼저 코드를 살펴보겠습니다. 🎜>
코드 복사
코드는 다음과 같습니다.
return {
get: function () {
return i;
},
set: function (val) {
i = val ; >},
increment: function () {
return i;
}
}
} ())// counter는 다중 개체입니다. 위 코드는 실제로 속성을
counter.get(); // 0
counter.set(3)
counter.increment() // 4
counter; .increment(); // 5
counter.i; // i가 반환된 객체의 속성이 아니기 때문에 정의되지 않았습니다.
i; // 참조 오류: i가 클로저에만 존재하기 때문에
모듈 패턴에 대한 자세한 소개를 보려면 이전 게시물인 JavaScript 시리즈 심층 이해(2): 모듈 패턴 종합 분석을 참조하세요.
더 읽어보기
위의 예를 통해 즉시 호출되는 함수(즉, 자체 실행 함수라고 부르는 함수)의 표현을 이해하는 데 도움이 되기를 바랍니다. 기능 및 모듈 패턴에 대한 자세한 내용을 보려면 아래 웹사이트를 계속 방문하세요.
ECMA-262-3에 대한 자세한 내용은 5장. 기능
- Dmitry A. Soshnikov
함수와 함수 범위
- Mozilla 개발자 네트워크
명명된 함수 표현식
- Juriy “kangax” Zaytsev
-
모듈 모드 종합 분석 - 벤 체리(삼촌 번역 및 편집)
-
JavaScript로 설명하는 클로저 - Nick Morgan