깊이 이해: 함수, 익명 함수, 자체 실행 함수, 패 킷 닫 기

7597 단어
1 함수 정의 방식
  • 함수 의 성명
  • 함수 표현 식
  • 1.1 함수 선언
    다음은 함수 성명 의 구조 입 니 다.
    function sum(x, y) {
        alert(x+y);
    }
    sum(1, 2);
    

    javascript 은 '함수 성명 향상' 의 특성 을 가지 고 있 기 때문에 코드 를 실행 하기 전에 함수 성명 을 먼저 읽 는 것 은 함수 성명 이 호출 된 문장 뒤에 놓 일 수 있 음 을 의미 합 니 다.다음 코드 는 정상적으로 실행 할 수 있 습 니 다.
    sum(1, 2);
    function sum(x, y) {
        alert(x+y);
    }
    

    1.2 함수 식
    함수 표현 식 에는 몇 가지 다른 문법 이 있다.가장 흔 하고 대표 적 인 것 은 코드 와 같다.
    var ss = function(x, y) {
        alert(x+y);
    }
    ss(1, 2);
    

    이런 형식 은 일반적인 변수 할당 문 처럼 보인다.그러나 함수 표현 식 과 함수 성명 의 차 이 는 함수 표현 식 을 사용 하기 전에 값 을 먼저 부여 해 야 한 다 는 것 이다.그래서 코드 가 실 행 될 때 오류 가 발생 합 니 다.
    ss(1, 2); //   ,  undefined is not a function
    var ss = function(x, y) {
        alert(x+y);
    }
    

    이 같은 현상 은 해석 기 가 실행 환경 에 데 이 터 를 불 러 올 때 해석 기 가 먼저 함수 성명 을 읽 고 모든 코드 를 실행 하기 전에 사용 할 수 있 도록 하기 때문이다.함수 표현 식 에 대해 서 는 해석 기 가 있 는 코드 줄 에 실 행 될 때 까지 기 다 려 야 진정 으로 해 석 될 수 있 습 니 다.함수 표현 식 에서 만 든 함 수 는 익명 함수 라 고 합 니 다. function 키워드 뒤에 식별 자가 없 기 때 문 입 니 다.
    2 익명 함수
    익명 함 수 는 말 그대로 이름 이 없 는 함수 다.위의 함수 표현 식 의 생 성, 즉 익명 함 수 를 만 들 고 익명 함 수 를 변수 ss 에 할당 합 니 다. ss 로 함수 호출 을 합 니 다. 호출 방식 은 변수 ss 뒤에 괄호 () 를 추가 하 는 것 입 니 다. 매개 변수 가 들 어 오 면 ss (1, 2) 입 니 다. 이것 이 바로 익명 함수 의 호출 방식 입 니 다.
    2.1 익명 함수 호출 방식
    또 하나의 익명 함수 호출 방식 은 1) 익명 함 수 를 () 로 묶 는 것 이다.2) 그리고 뒤에 작은 괄호 (매개 변수 목록 포함) 를 추가 합 니 다.우 리 는 다음 과 같은 예 를 다시 한 번 보 자.
    alert((function(x, y){return x+y;})(2, 3));
    // Function   ( ),     arg      ,           ,         。              NodeJS          
    alert((new Function('x', 'y', 'return x+y;'))(2, 3)); 
    

    javascript 에 서 는 블록 급 역할 영역 이 없다 는 표현 입 니 다. 상기 코드 의 이러한 방식 은 블록 급 역할 영역 (일반적으로 사유 역할 영역 이 됨) 을 모방 한 것 입 니 다. 문법 은 다음 과 같 습 니 다.
    function() {
        //        
    }();
    

    이상 코드 는 익명 함 수 를 정의 하고 즉시 호출 하 였 습 니 다.함수 성명 을 통 해 원 괄호 에 포함 되 어 있 으 며, 이것 은 실제 함수 표현 식 임 을 나타 낸다.다음 괄호 는 이 함 수 를 즉시 호출 합 니 다.
    function() {
        //        
    }();
    

    주의: 상기 코드 가 잘못 보 고 될 수 있 습 니 다 Uncaught SyntaxError: Unexpected token(Javascript 은 function 키 워드 를 함수 성명 의 시작 으로 생각 하기 때문에 함수 성명 뒤에 괄호 를 붙 일 수 없습니다. 컴 파 일 러 를 표시 하지 않 으 면 이름 이 없 는 function 을 기본적으로 생 성하 고 문법 오 류 를 던 집 니 다. function 소리 에 이름 이 필요 하기 때 문 입 니 다. 재 미 있 는 것 은 위의 잘못된 코드 에 이름 을 추가 하 더 라 도그 는 문법 오 류 를 제시 하기 도 합 니 다. 위의 원인 과 다 를 뿐 입 니 다. 한 표현 식 뒤에 괄호 () 를 붙 이면 이 표현 식 은 즉시 실 행 됩 니 다. 그러나 한 문장 뒤에 괄호 () 를 붙 이 는 것 은 전혀 다른 뜻 입 니 다. 그 는 그룹 연산 자 일 뿐 입 니 다.
    //   function         ,          
    //     ()       ,                
    function foo(){ /* code */ }(); // SyntaxError: Unexpected token )  
       
    //         ()        ,          
    //   foo          
    function foo(){ /* code */ }( 1 );  
       
    //               ,  function    ,              :   
    function foo(){ /* code */ }  
       
    ( 1 );  
    
    

    따라서 상기 코드 가 정확하게 실현 되 려 면 반드시 할당 을 실현 해 야 합 니 다. 예 를 들 어 a = function(){}(), "a =" 이것 은 컴 파일 러 에 게 함수 성명 이 아니 라 함수 표현 식 이 라 고 알려 주 었 습 니 다. 함수 표현 식 뒤에 () 를 따라 갈 수 있 기 때문에 아래 두 단락 의 코드 는 등가 입 니 다.
    var aa = function(x) {
        alert(x);
    }(5); // 5
    
    (function(x){alert(x);})(5);
    

    위 에서 함수 와 익명 함수 에 대한 이 해 를 가지 고 있 습 니 다. 우 리 는 자체 실행 함수 라 는 개념 을 인용 하여 이 유 를 더욱 깊이 이해 하 게 합 니 다. a = function () {} () 이 표 시 는 컴 파일 러 로 하여 금 함수 가 아 닌 함수 표현 식 이 라 고 생각 하 게 할 수 있 습 니 다.
    3 자체 실행 함수
    우 리 는 익명 의 함 수 를 만 들 고 즉시 실행 합 니 다. 외부 에서 내부 변 수 를 참조 할 수 없 기 때문에 실행 이 끝 난 후에 곧 풀 려 날 것 입 니 다. 관건 은 이러한 메커니즘 이 전체 대상 을 오염 시 키 지 않 는 다 는 것 입 니 다. 자체 실행 함수, 즉 정의 와 호출 을 하나 로 합 치 는 것 입 니 다.
    실행 함수 의 일부 표현 방식:
    //   2   ()        
    (function () { /* code */ } ()); //         
    (function () { /* code */ })(); //           
    

    폐쇄
    패 킷 을 닫 는 것 은 다른 함수 역할 도 메 인 에 접근 할 수 있 는 변 수 를 말 합 니 다. 패 킷 을 닫 는 일반적인 방식 은 함수 내부 에 다른 함 수 를 만 드 는 것 입 니 다. 패 킷 을 닫 는 것 은 주로 js 의 몇 가지 다른 특성 과 관련 됩 니 다. 역할 도 메 인 체인, 쓰레기 (메모리) 회수 체제, 함수 내장 등 입 니 다.
    4.1 패 킷 을 닫 는 간단 한 예
    일반적인 상황 에서 함수 내 부 는 함수 외부의 전역 변 수 를 방문 할 수 있 습 니 다.
     var a = 1;//      
     function f1(){  
         alert(a);  
     }  
     f1();//1 
    

    함수 외부 에서 함수 내부 의 부분 변 수 를 방문 할 수 없습니다.
    function f2(){  
        var a = 1 ; //      
    }  
    alert(a); //error  
    

    때때로 우 리 는 함수 내부 의 국부 변 수 를 얻 으 려 면 어떻게 실현 해 야 합 니까? 이것 은 폐쇄 적 인 개념 을 도입 합 니 다.
    function fn1() {
        var n = 1;
    
        return function() {
            alert(n);
        }
    }
    result = fn1();
    result();
    

    4.2 폐쇄 적 역할
  • 함수 내부 의 변 수 를 읽 기
  • 변수의 값 을 항상 메모리 에 저장 합 니 다
  • 일반적으로 함수 가 실 행 된 후에 함수 내부 의 부분 활동 대상 은 삭 제 됩 니 다. 메모리 에는 전역 역할 도 메 인, 즉 js 의 메모리 회수 메커니즘 만 저장 합 니 다. 만약 이 함수 내부 에 또 다른 함수 가 포함 되 어 있다 면 이 함 수 는 외부 에서 호출 될 수 있 습 니 다. 그리고 이 내부 함수 가 외부 함수 의 일부 변 수 를 사용 했다 면. 이러한 메모리회수 메커니즘 에 문제 가 생 길 수 있 습 니 다. 외부 함수 가 돌아 온 후에 내부 함 수 를 직접 호출 하면 내부 함 수 는 그 가 필요 로 하 는 외부 함수 에서 변수의 값 을 읽 을 수 없습니다. 따라서 js 해석 기 는 함수 정 의 를 만 났 을 때 함수 와 그 가 사용 할 수 있 는 변수 (로 컬 변수 와 부모 급, 조상 급 함수 의 변수 (자유 변수 포함) 를 자동 으로 사용 합 니 다.같이 저장 합 니 다. 즉, 패 킷 을 구축 하 는 것 입 니 다. 이 변 수 는 메모리 회수 기 에 의 해 회수 되 지 않 습 니 다. 내부 함수 가 호출 되 지 않 을 때 (예 를 들 어 삭제 되 거나 지침 이 없 을 때) 이 패 킷 을 없 앨 수 있 습 니 다. 패 킷 참조 변 수 는 다음 메모리 회수 가 시 작 될 때 회수 되 지 않 습 니 다.
    4.3 주의사항
  • 패 킷 을 닫 으 면 함수 의 변 수 를 메모리 에 저장 하고 메모리 소모 가 크기 때문에 패 킷 을 남용 해 서 는 안 됩 니 다. 그렇지 않 으 면 웹 페이지 의 성능 에 문제 가 생 겨 IE 에서 메모리 가 유출 될 수 있 습 니 다. 해결 방법 은 함 수 를 종료 하기 전에 사용 하지 않 는 부분 변 수 를 모두 삭제 하 는 것 입 니 다.
  • 패 키 지 는 부모 함수 외부 에서 부모 함수 내부 변수의 값 을 변경 합 니 다. 따라서 부모 함 수 를 대상 (object) 으로 사용 하면 패 키 지 를 공용 방법 (Public Method) 으로 사용 하고 내부 변 수 를 개인 속성 (private value) 으로 간주 할 때 부모 함수 내부 변수의 값 을 함부로 바 꾸 지 않도록 조심해 야 합 니 다.
  • 5 자체 실행 함수 와 패키지 사용
    많은 경우 자체 실행 함수 와 패 킷 을 이용 하여 특정한 특수 상태의 값 을 저장 할 수 있 습 니 다. 도 메 인 체인 의 설정 체제 로 인해 패 킷 은 함수 에 있 는 모든 변 수 를 포함 하 는 마지막 값 만 얻 을 수 있 습 니 다. 즉, 패 킷 에 저 장 된 것 은 특정한 변수 가 아 닌 전체 변수 대상 임 을 설명 합 니 다. 우 리 는 아래 의 예 를 들 어 이 문 제 를 설명 합 니 다.예 1:
    function createFunction() {
        var result = new Array();
        for( var i = 0; i<10; i++) {
            result[i] = function() {
                return i;
            };
        }
        return result;
    }
    
    var aa = createFunction();
    alert(aa[0]()); //10
    alert(aa[1]()); //10
    
  • 이 함수 에 서 는 패 킷 할당 값 을 배열 에 직접 부여 합 니 다. 이 함 수 는 함수 배열 을 되 돌려 줍 니 다. 겉 으로 는 모든 함수 가 자신의 색인 으로 돌아 가 야 할 것 같 습 니 다. 즉, 0 의 함 수 는 0 으로 되 돌아 가 고, 위치 1 의 함 수 는 1 번 으로 유추 합 니 다. 그러나 실제로 위의 예 와 같이 모든 함수 가 10 으로 되 돌아 갑 니 다. 각 함수 의 역할 도 메 인 체인 에 저장 되 어 있 기 때 문 입 니 다.createFunctions () 함수 의 활동 대상 이기 때문에 같은 변수 i 를 참조 합 니 다. createFunctions () 함수 가 돌아 오 면 변수 i 의 값 이 10 이 죽 습 니 다. 이때 함수 마다 변 수 를 저장 하 는 같은 변 수 를 참조 합 니 다. 따라서 함수 내부 i 의 값 은 10 입 니 다.
  • 따라서 우 리 는 다음 과 같은 예 를 통 해 자체 실행 함수 (익명 함수) 를 만들어 서 패 킷 을 닫 는 행 위 를 기대 에 부합 하도록 강제 할 수 있 습 니 다. 예 2:
  • function createFunction() {
        var result = new Array();
        for( var i = 0; i<10; i++) {
            result[i] = function(num) {
                return function() {
                    return num;
                };
            }(i);
        }
        return result;
    }
    
    var bb = createFunction();
    alert(aa[0]()); //0
    alert(aa[1]()); //1
    

    예 2 에서 우 리 는 패키지 할당 값 을 배열 에 직접 부여 하지 않 고 익명 함 수 를 정의 하 였 으 며, 이 익명 함수 의 결 과 를 즉시 배열 에 할당 하 였 습 니 다. 즉시 실 행 된 익명 함수 에 대해 서 는 외부 에서 내부 변 수 를 참조 할 수 없 기 때문에 실행 이 끝 난 후 곧 풀 릴 것 입 니 다. 따라서 여기 익명 함수 에는 하나의 인자 num, 즉 가장 좋 은 인자 가 있 습 니 다.마지막 함수 가 되 돌려 줄 값 입 니 다. 모든 익명 함 수 를 호출 할 때 변수 i 를 입력 했 습 니 다. 함수 가 값 에 따라 전달 되 기 때문에 변수 i 의 현재 값 을 매개 변수 num 에 할당 합 니 다. 이 익명 함수 내 부 는 num 으로 돌아 가 는 패 키 지 를 만 들 고 되 돌려 줍 니 다. 이렇게 하면 result 배열 의 모든 함수 가 자신의 num 복사 본 을 가지 고 있 기 때문에 되 돌 릴 수 있 습 니 다.각자 다른 수치 로 돌 아 왔 습 니 다.

    좋은 웹페이지 즐겨찾기