역할 영역 폐쇄

6660 단어 자바 script
역할 영역 폐쇄 의 내용 을 설명 하기 전에 다음 과 같은 개념 을 파악 해 야 한다.
  • JavaScript 는 두 가지 역할 도 메 인 을 가지 고 있 습 니 다. 전체 역할 도 메 인과 함수 역할 도 메 인 은 블록 역할 도 메 인 에 대해 서도 없다 고 할 수 없습니다. 예 를 들 어 try.. catch.. 문장 에서 catch 분 구 는 블록 역할 도 메 인 이 고 with 문장 등 이 있 습 니 다.
  • ES6 의 let 키 워드 는 임의의 코드 블록 에서 변 수 를 설명 할 수 있 습 니 다.
  • 함수 표현 식 과 그 역할 을 즉시 수행 하 는 것 은 무엇 입 니까?

  • 늙은이 는 늘 폐쇄 가 무엇 인지 이야기한다
    패 킷 의 개념: 함수 가 있 는 품사 작용 도 메 인 을 기억 하고 방문 할 수 있 을 때 함수 가 현재 품사 작용 도 메 인 밖에서 실행 되 더 라 도 이 때 패 킷 이 생 긴 다.
        function foo(){
            var a = 2;
            function bar(){
                console.log(a);
            }
            return bar;
        }
        var baz = foo();
        baz(); //        

    함수 bar () 의 품사 역할 도 메 인 은 foo () 의 내부 역할 도 메 인 에 접근 한 다음 에 우 리 는 bar () 함수 자 체 를 하나의 값 으로 전달 할 수 있 습 니 다.foo () 가 실 행 된 후에 반환 값 은 변수 baz 에 할당 되 고 baz () 를 호출 합 니 다.foo () 가 실 행 된 후, 일반적으로 foo () 의 전체 내부 작용 이 모두 폐기 되 기 를 기대 합 니 다. 왜냐하면 우 리 는 엔진 에 쓰레기 회수 메커니즘 이 있어 서 사용 하지 않 는 메모리 공간 을 방출 하 는 것 을 알 고 있 기 때 문 입 니 다.foo () 의 내용 이 더 이상 사용 되 지 않 을 것 으로 보이 기 때문에 자 연 스 럽 게 재 활용 을 고려 합 니 다.하지만 가방 을 닫 는 신기 한 점 은 이 를 막 을 수 있다 는 점 이다.사실상 내부 작용 역 은 여전히 존재 하기 때문에 회수 되 지 않 았 다.그렇다면 누가 이 내부 작용 역 을 사용 하고 있 습 니까?당연히 bar () 가 사용 하고 있 습 니 다.bar () 는 foo () 함수 내부 에 있 기 때문에 foo () 내부 역할 도 메 인 을 포함 하 는 패 키 지 를 가지 고 있 습 니 다. 이 역할 도 메 인 은 앞으로 언제든지 참조 할 수 있 도록 생존 할 수 있 습 니 다.bar () 함 수 는 foo () 호출 이 끝 난 후에 도 그 역할 영역 에 대한 인용 을 가지 고 있 습 니 다. 이 인용 을 폐쇄 라 고 합 니 다.
    물론 어떤 방식 으로 함수 유형의 값 을 전달 하 든 함수 가 다른 곳 에서 호출 될 때 폐쇄 를 관찰 할 수 있 습 니 다.
        function foo(){
            var a = 2;
            function baz(){
                console.log(a)//2
            }
            bar(baz);
        }
        function bar(fn){
            fn(); //     
        }
    

    위의 코드 의 무미건조 함 보다 더 흔히 볼 수 있 는 예 가 있다
        function wait(message){
            setTimeout(function time(){
                console.log(message);
            }, 1000);
        }
        wait("hello clousre");
    

    이 코드 를 간단하게 분석 해 보 세 요. 우 리 는 time 이라는 내부 함 수 를 setTimeout () 에 전달 합 니 다. time 은 wait () 역할 도 메 인 을 포함 하 는 패 키 지 를 가지 고 있 기 때문에 변수 message 에 대한 인용 도 가지 고 있 습 니 다.wait (..) 1000 ms 를 실행 한 후 내부 역할 영역 은 사라 지지 않 습 니 다. time () 함 수 는 wait () 역할 영역 에 대한 패 키 지 를 가지 고 있 습 니 다. 엔진 내부 에 내 장 된 도구 함수 setTimeout () 은 매개 변수 에 대한 인용 을 가지 고 있 습 니 다. 이 매개 변 수 는 fn 또는 func 라 고 할 수 있 습 니 다.엔진 은 이 함 수 를 호출 할 것 이 며, 품사 작용 도 메 인 은 이 과정 에서 완전 함 을 유지 할 것 이다.이게 폐쇄 야.
    그럼 폐쇄 는 어떤 앱 이 있 나 요?사실은 타이머, 이벤트 감청 기, Ajax 요청, 크로스 창 통신, 웹 Workers 또는 다른 비동기 (또는 동기 화) 작업 을 포함 합 니 다. 반환 함 수 를 사용 하면 사실상 패 킷 을 사용 합 니 다!
    여기 서 우 리 는 특히 전형 적 인 폐쇄 적 인 예 를 다시 보 았 지만 엄 밀 히 말 하면 그것 은 폐쇄 적 인 것 이 아니다.
    var a = 2;
    (function IIFE(){
        console.log(a)
    })();
    

    IIFE 는 함수 표현 식 을 즉시 실행 합 니 다. 첫 번 째 () 는 함 수 를 함수 표현 식 으로 바 꾸 고 두 번 째 () 함 수 는 실 행 됩 니 다.왜 그 가 엄격하게 말하자면 결코 폐쇄 적 인 것 이 아니 라 고 말 합 니까?예제 코드 에서 함 수 는 그 자체 의 품사 역할 영역 밖에서 실 행 된 것 이 아니 기 때문에 그 정의 에 있 는 역할 영역 에서 실 행 됩 니 다. a 는 품사 역할 영역 을 통 해 찾 은 것 이지 폐쇄 적 으로 발견 한 것 이 아 닙 니 다.IIFE 자체 가 폐쇄 를 관찰 하 는 적절 한 예 는 아니 지만 그 는 폐쇄 된 역할 도 메 인 을 만 들 었 고 폐쇄 된 폐쇄 도 구 를 만 드 는 데 가장 많이 사용 되 었 다.
    순환 과 폐쇄
    폐쇄 적 으로 우리 가 접촉 한 최초의 것 은 아마도 for 순환 의 예 일 것 이다.
        for(var i = 1; i<6; i++){
            setTImeout(function time(){
                console.log(i)
            }, i*1000)
        }

    이 코드 를 처음 봤 을 때, 그것 은 깊 은 학 대 를 받 았 습 니 다. C 언어 로 시작 한 친구 입 니 다. 그 때 는 정말 멍청 한 얼굴 이 었 습 니 다. 왜 5 개 6 을 수출 했 습 니까? 왜 5 개 6 을 수출 했 습 니까? 왜 요?당시 에 다른 사람들의 설명 도 모호 했다. 비록 해결 방법 을 제 시 했 지만 그 중의 메커니즘 원 리 를 이해 할 수 없 었 기 때문에 나 는 그것 을 이해 하기 로 마음 먹었다!나 만 모 르 겠 지!
    가: 왜 66666 을 출력 합 니까?답: 66666 을 출력 할 수 있 는 것 은 for 순환 내부 의 코드 가 확실히 5 번 실행 되 었 다 는 것 을 설명 합 니 다.가: 그럼 6 은 어디서 났 어 요?답: 6 은 우리 가 순환 하 는 종료 조건 이기 때문에 출력 6.― 그럼 왜 한 번 순환 하지 않 고 한 값 을 출력 합 니까? 1, 2, 3, 4, 5 이렇게 합 니까?답: setTimeout () 함 수 는 순환 이 끝 날 때 실 행 됩 니 다. setTimeout (fn, 0) 을 설정 하 더 라 도 for 순환 이 끝 난 후에 바로 실 행 됩 니 다. 어쨌든 for 순환 이 끝 난 후에 실 행 됩 니 다.
    자, 왜 66666 을 수출 했 는 지 이해 하기 어렵 지 않 습 니 다.그러나 이것 은 더욱 깊 은 화 제 를 불 러 일 으 켰 다. 코드 에서 도대체 어떤 결함 이 그의 행 위 를 의미 암시 와 일치 하지 않 게 만 들 었 을 까?
    결함: 우 리 는 순환 중의 모든 교체 가 실 행 될 때 자신 에 게 i 의 사본 을 캡 처 한다 고 가정 하려 고 합 니 다.그러나 작용 역 의 작업 원리 에 따라 실제 상황 은 순환 중의 다섯 개의 함수 가 각 교체 에서 각각 정의 되 었 음 에 도 불구 하고 모두 공 유 된 전역 작용 역 에 갇 혀 있 기 때문에 실제 적 으로 i 만 있다.그래서 실제 모습 은 이렇다.
    우리 가 상상 하 는 모습 은 그렇다.
    다음은 본론 으로 돌아 가 겠 습 니 다.결함 이 무엇 인지 알 게 된 이상 어떻게 해 야 우리 가 상상 하 는 모습 을 이 룰 수 있 을 까?정 답 은 우리 가 매번 교체 하 는 과정 에서 폐쇄 작용 역 을 만들어 야 한 다 는 것 이다.위의 글 에서 우 리 는 이미 깔 려 있 습 니 다. IIFE 는 성명 을 통 해 함수 하 나 를 즉시 실행 하여 역할 영역 을 만 들 것 입 니 다.so 우 리 는 코드 를 아래 의 모양 으로 바 꿀 수 있다.
        for(var i=1; i<6; i++){
            (function(){
                setTImeout(function time(){
                    console.log(i)
                }, i*1000)
            })();
        }

    이렇게 매번 교체 할 때마다 우 리 는 폐쇄 적 인 역할 영역 을 만 들 었 다.그러나 이렇게 해도 여전히 안 된다. 왜 일 까?지연 함수 마다 IIFE 가 매번 교체 할 때마다 만 든 역할 영역 을 닫 지만 우리 가 폐쇄 한 역할 영역 은 비어 있 기 때문에 우리 가 원 하 는 결 과 를 얻 기 위해 서 는 무언 가 를 전달 해 야 합 니 다.
        for(var i=1; i<6; i++){
            (function(){
                var j = i
                setTImeout(function time(){
                    console.log(j)
                }, j*1000)
            })();
        }

    ok!지금 그 가 정상적으로 일 할 수 있 는 지 시험 해 보 시 겠 습 니까?이 코드 를 좀 더 개선 하 다.
        for(var i=1; i<6; i++){
            (function(j){
                setTImeout(function time(){
                    console.log(j)
                }, j*1000)
            })(i);
        }

    전체적으로 말 하면 교체 에서 IIFE 를 사용 하면 모든 교체 에 새로운 역할 도 메 인 을 생 성하 고 지연 함수 가 새로운 역할 도 메 인 을 모든 교체 내부 에 폐쇄 할 수 있 습 니 다. 우 리 는 교체 하 는 과정 에서 매번 교체 하 는 i 값 을 매개 변수 로 새로운 역할 도 메 인 에 전달 할 수 있 습 니 다.이렇게 교체 에서 만 든 폐쇄 작용 도 메 인 은 우리 가 방문 할 수 있 도록 정확 한 값 을 가 진 변 수 를 포함 할 것 이다.ok,it's work!
    블록 역할 영역
    우리 앞의 해결 방안 을 자세히 생각 하 다.우 리 는 IIFE 를 사용 하여 매번 교체 할 때마다 새로운 역할 영역 을 만 듭 니 다.즉, 매번 교체 할 때마다 우 리 는 하나의 작용 역 이 필요 하 다 는 것 이다.앞에서 언급 했 듯 이 ES6 의 let 키 워드 를 알 아야 합 니 다. 블록 역할 영역 을 납치 하고 이 역할 영역 에서 변 수 를 설명 할 수 있 습 니 다.본질 적 으로 그것 은 블록 을 닫 을 수 있 는 역할 영역 으로 바 꾸 는 것 이다.
        for(var i=1; i<6; i++){
                let j = i; //       
                setTImeout(function time(){
                    console.log(j)
                }, j*1000)
        }
    

    let 를 for 순환 의 머리 에 설명 한다 면 특별한 행동 이 있 을 것 입 니 다. 얼마나 특별한 가요?이 는 변 수 는 순환 과정 에서 한 번 만 설명 되 는 것 이 아니 라 매번 교체 할 때마다 설명 된다 고 지적 할 것 이다.다음 의 모든 교 체 는 이전 교체 가 끝 날 때의 값 을 사용 하여 이 변 수 를 초기 화 합 니 다.이 말 이 아무리 까다 로 워 도 코드 를 보 세 요!
            for(let i=1; i<6; i++){
                setTImeout(function time(){
                    console.log(i)
                }, i*1000)
        }
    
    

    어디서 많이 본 듯 한 느낌 이 들 었 는 지, 감동 이 들 었 는 지, 나 는 이미 눈물 을 흘 렸 다.............................................
    다음 절 은 패키지 활용 - 모듈 메커니즘

    좋은 웹페이지 즐겨찾기