자 바스 크 립 트 패키지 새 버 전 깊이 이해
3926 단어 자 바스 크 립 트 폐쇄
function a(){
var i=0;
function b(){
alert(++i);
}
return b;
}
var c = a();
c();
이 코드 는 두 가지 특징 이 있 습 니 다.1.함수 b 는 함수 a 내부 에 포함 되 어 있 습 니 다.2.함수 a 반환 함수 b.이렇게 하면 var c=a()를 실행 한 후에 변수 c 는 실제 함수 b 를 가리 키 고 c()를 실행 하면 창 에 i 의 값 을 표시 합 니 다(첫 번 째 는 1).이 코드 는 사실 폐쇄 를 만 들 었 습 니 다.왜 요?함수 a 밖의 변수 c 는 함수 a 내의 함수 b 를 인 용 했 기 때 문 입 니 다.즉,함수 a 의 내부 함수 b 가 함수 a 밖의 변수 에 의 해 인 용 될 때 닫 힌 패 키 지 를 만 듭 니 다.나 는 네가 가방 을 닫 는 것 이 무슨 작용 을 하 는 지 모 르 기 때문에 우 리 는 계속 탐색 할 것 이 라 고 추측 했다.2.폐쇄 는 어떤 역할 을 합 니까?한 마디 로 하면 패 킷 을 닫 는 역할 은 a 가 실행 하고 돌아 온 후에 패 킷 을 닫 아서 자 바스 크 립 트 의 쓰레기 회수 메커니즘 GC 가 a 가 차지 하 는 자원 을 회수 하지 못 하 게 하 는 것 이다.a 의 내부 함수 b 의 실행 은 a 의 변수 에 의존 해 야 하기 때문이다.이것 은 폐쇄 작용 에 대한 매우 직 설 적 인 묘사 로 전문 적 이지 도 엄밀 하지 도 않 지만 대충 말 하면 폐쇄 작용 을 이해 하 는 데 순서에 따라 점진 적 인 과정 이 필요 하 다 는 것 이다.위의 예 에서 패 킷 의 존재 로 인해 함수 a 가 돌아 온 후에 a 중의 i 는 항상 존재 합 니 다.이렇게 매번 c()를 실행 할 때마다 i 는 1 을 추가 한 후에 alert 에서 i 의 값 을 냅 니 다.그러면 우 리 는 다른 상황 을 상상 해 보 자.만약 에 a 가 함수 b 가 아니라면 상황 은 완전히 다르다.a 가 실 행 된 후에 b 는 a 의 외부 로 돌아 가지 않 고 a 에 의 해 인용 되 었 을 뿐 이 고 이때 a 도 b 에 의 해 인용 되 었 기 때문에 함수 a 와 b 는 서로 인용 되 지만 외부 에 의 해 방 해 받 지 않 고 함수 a 와 b 는 GC 에 의 해 회수 된다.(자 바스 크 립 트 의 쓰레기 회수 메커니즘 에 대해 서 는 뒤에 상세 하 게 소개 할 것 입 니 다.3.패키지 안의 미시적 인 세 계 를 더욱 깊이 이해 하려 면 패키지 와 함수 a 와 내장 함수 b 의 관 계 를 이해 하려 면 함수 의 집행 환경(excution context),활동 대상(callobject),역할 영역(scope),역할 영역 체인(scope chain)을 도입 해 야 합 니 다.함수 a 가 정의 에서 실행 까지 의 과정 을 예 로 들 어 이 몇 가지 개념 을 논술 하 다.1.함수 a 를 정의 할 때 js 해석 기 는 함수 a 의 역할 도 메 인 체인(scope chain)을 a 를 정의 할 때 a 가 있 는'환경'으로 설정 합 니 다.a 가 전체 함수 라면 scope chain 에는 window 대상 만 있 습 니 다.2.함수 a 가 실 행 될 때 a 는 해당 하 는 실행 환경(excution context)에 들 어 갑 니 다.3.실행 환경 을 만 드 는 과정 에서 먼저 a 에 scope 속성,즉 a 의 역할 영역 을 추가 합 니 다.그 값 은 첫 번 째 단계 의 scope chain 입 니 다.즉 a.scope=a 의 역할 도 메 인 체인 입 니 다.4.그리고 실행 환경 에서 활동 대상(callobject)을 만 듭 니 다.활동 대상 도 속성 을 가 진 대상 이지 만 원형 이 없 으 며 자바 스 크 립 트 코드 를 통 해 직접 접근 할 수 없습니다.이벤트 대상 을 만 든 후 이벤트 대상 을 a 의 역할 도 메 인 체인 의 맨 위 에 추가 합 니 다.이때 a 의 역할 도 메 인 체인 은 두 개의 대상 을 포함한다.a 의 활동 대상 과 window 대상 이다.5.다음 단 계 는 이벤트 대상 에 arguments 속성 을 추가 하 는 것 입 니 다.함수 a 를 호출 할 때 전달 하 는 인 자 를 저장 합 니 다.6.마지막 으로 모든 함수 a 의 형 삼 과 내부 함수 b 의 인용 을 a 의 활동 대상 에 추가 합 니 다.이 단계 에서 함수 b 의 정 의 를 완 성 했 기 때문에 3 단계 와 같이 함수 b 의 역할 도 메 인 체인 은 b 가 정의 하 는 환경,즉 a 의 역할 도 메 인 으로 설정 되 었 습 니 다.이로써 전체 함수 a 는 정의 에서 실행 까지 의 절차 가 완성 되 었 다.이때 a 반환 함수 b 의 인용 은 c 에 있 고 함수 b 의 역할 도 메 인 체인 은 함수 a 의 활동 대상 에 대한 인용 을 포함 합 니 다.즉,b 는 a 에서 정의 하 는 모든 변수 와 함수 에 접근 할 수 있 습 니 다.함수 b 는 c 에 의 해 인용 되 고 함수 b 는 함수 a 에 의존 하기 때문에 함수 a 는 되 돌아 온 후에 GC 에 의 해 회수 되 지 않 습 니 다.함수 b 가 실 행 될 때 도 상기 절차 와 같 습 니 다.따라서 실행 할 때 b 의 역할 도 메 인 체인 은 3 개의 대상 을 포함 합 니 다.b 의 활동 대상,a 의 활동 대상 과 window 대상 은 다음 그림 과 같 습 니 다.그림 에서 보 듯 이 함수 b 에서 변 수 를 방문 할 때 검색 순 서 는 자신의 활동 대상 을 먼저 검색 하고 존재 하면 되 돌아 갑 니 다.존재 하지 않 으 면 함수 a 의 활동 대상 을 계속 검색 하고 순서대로 찾 습 니 다.찾 을 때 까지전체 역할 영역 체인 에서 찾 을 수 없다 면 undefined 로 돌아 갑 니 다.함수 b 에 prototype 프로 토 타 입 대상 이 존재 한다 면 자신의 활동 대상 을 찾 은 후에 자신의 프로 토 타 입 대상 을 찾 은 다음 에 계속 찾 습 니 다.이것 이 바로 자바 script 의 변수 찾기 메커니즘 입 니 다.4.패 킷 을 닫 는 응용 장면 1.함수 안의 변수 안전 을 보호 합 니 다.최초의 예 를 들 어 함수 a 에서 i 는 함수 b 만 접근 할 수 있 고 다른 경 로 를 통 해 접근 할 수 없 기 때문에 i 의 안전성 을 보호 합 니 다.2.메모리 에 변 수 를 유지 합 니 다.여전히 전례 와 같이 패 킷 을 닫 기 때문에 함수 a 에 i 가 메모리 에 존재 하기 때문에 c()를 실행 할 때마다 i 에 1 을 추가 합 니 다.상기 두 가 지 는 폐쇄 적 이 고 가장 기본 적 인 응용 장면 으로 많은 전형 적 인 사례 가 여기 서 기원 되 었 다.5.Javascript 의 쓰레기 수 거 체 제 는 Javascript 에서 한 대상 이 더 이상 인용 되 지 않 으 면 이 대상 은 GC 에 의 해 수 거 됩 니 다.만약 두 대상 이 서로 인용 되 고 제3자 에 게 인용 되 지 않 는 다 면,이 두 대상 도 서로 인용 되 는 대상 은 회 수 될 것 이다.함수 a 는 b 에 의 해 인용 되 고 b 는 a 밖의 c 에 의 해 인용 되 기 때문에 이것 이 바로 함수 a 가 실 행 된 후에 회수 되 지 않 는 이유 입 니 다.