폐쇄 구조 모듈 (기초 편) 사용 - Object - Oriented Javascript 의 3

11283 단어 JavaScript
왜 js 를 모듈 화 합 니까?
만약 네가 나 에 게 이 문 제 를 묻는다 면 나 는 이렇게 대답 할 것 이다.
전역 변수 에 구 애 된 적 이 없다 면 길 을 돌아 가세 요.
만약 당신 이 큰 코드 를 유지 하 는 악몽 을 꾼 적 이 없다 면, 나 는 당신 의 새해 가 즐 겁 고 일찍 무사히 집에 돌아 가 기 를 바 랍 니 다.
만약 당신 이 코드 를 우아 하 게 조직 하 는 방법 에 대해 고민 한 적 이 없다 면, 고 개 를 돌리 면 해안 이 고, 다 시 는 아래 를 보지 마 세 요.
 
모듈 의 기본 사상 은 복잡 하고 흩 어 진 것 을 간단 하고 독립 된 전체 로 구성 하 는 것 이다.데스크 톱, 노트북, IPAD 는 모두 전자 계산 부품 을 통합 하 는 전형 적 인 '모듈' 이다. 그들 내부 에 D 트리거 를 얼마나 사 용 했 는 지, 다이오드 를 얼마나 사 용 했 는 지 신경 쓰 지 않 아 도 된다. 마우스 키보드 나 터치 스크린 이 주 는 편안 한 체험 을 즐 길 수 있다.데스크 톱, 노트북, IPAD 는 모두 같은 전자 제품 의 모듈 이지 만 하나 보다 간단 하고 하나 보다 더 사 랑 받 을 수 있다.모듈 화 는 상상력 과 창조력 의 일 로 추구 만 있 으 면 더욱 아름 다운 모듈 을 만 들 수 있다 (조심 하지 않 으 면 이 관점 은 너무 높 은 것 같다).본 고 는 필자 가 가장 좋아 하 는 모듈 화 방식 을 소개 하고 독자 의 비판 과 지 도 를 받 고 더 많은 사람들 이 모듈 화 된 영감 을 불 러 일 으 키 기 를 바란다.
 
다음은 본론 으로 들 어 갑 니 다. 폐쇄 구조 모듈 을 사용 합 니 다. 
 디 렉 터 리:
이해: 세 가지 역할 영역
이해: 폐쇄 = 역할 영역 사유 성 + 역할 영역 지속 성
실천: 폐쇄 구 조 를 사용 하여 간단 한 모듈, 단일 공장
 
이해: 세 가지 역할 영역
javascript 의 역할 영역 은 세 가지 가 있 습 니 다. 하 나 는 global 이 고 하 나 는 local 이 며 하 나 는 closure 입 니 다.chrome debug 를 사용 할 때 각 역할 영역 에서 어떤 변 수 를 볼 수 있 는 지 뚜렷하게 볼 수 있 습 니 다.첫 번 째 는 설명 이 많 지 않 습 니 다. 브 라 우 저 에서 global 역할 영역 은 사실 window 입 니 다.두 번 째 와 세 번 째 는 개인 적 으로 함수 역할 영역 이 라 고 생각 합 니 다.closure 역할 영역 은 현재 실행 중인 함수 의 함수 역할 영역 에서 변 수 를 찾 은 것 이 아니 라 부모 함수 역할 영역 에서 변 수 를 찾 았 습 니 다. 부모 함수 가 실행 되 었 더 라 도.
<!DOCTYPE HTML>
<HTML>
 <HEAD>
  <TITLE>3    </TITLE>
 </HEAD>

 <BODY>
  <script>
	var gLanuageName = "javascript";//global   
	function func(){
		var a = 2;
		if(2 === a){
			var b = 3;
		}
		alert(b);//function      b

		var funcDouble = function(){
			return 2 * a;//closure      a
		};
		
		(function(){
			alert(gLanuageName);//global      gLanuageName
		})();

		return funcDouble;
	}
	var funcDouble = func();
	alert(funcDouble());//funcDouble func    ,func     ,         a  。
	alert(gLanuageName);//global     gLanuageName

  </script>
 </BODY>
</HTML>
 
이해 함수 역할 영역
아래 의 절 차 를 읽 으 면 결과 가 뭐라고 생각 합 니까?undefined? 3?
<script>
	function func(){
		var a = 2;
		if(2 === a){
			var b = 3;
		}
		alert(b);
	}
	func();
  </script>
 
위의 코드 를 보 세 요. 자바 script 의 역할 도 메 인 을 자바 의 역할 도 메 인 으로 이해 하면 b 는 undefined 입 니 다.그러나 프로그램 을 실행 한 결 과 는 b = = 3 이다.왜 b 는 3 이지 undefined 가 아 닙 니까?js 의 역할 영역 은 함수 역할 영역 이기 때문에 for, if, swthich 키워드 뒤의 {} 은 역할 영역 이 아니 라 function () 뒤의 {} 이 야 말로 역할 영역 입 니 다.프로그램 에서 var b = 3 과 alert (b) 는 같은 함수 역할 영역 에 있 기 때문에 alert (b) 는 3 입 니 다.
 
javascript 의 역할 영역 은 체인 역할 영역 입 니 다.
현재 역할 영역 에서 변 수 를 찾 지 못 하면 부모 역할 영역 에서 이 변 수 를 찾 습 니 다. 가장 바깥쪽 역할 영역 위치 까지.
<script>
	var gLanuageName = "javascript";//global   
	function func(){
		var a = 2;
		if(2 === a){
			var b = 3;
		}
		alert(b);//function      b

		var funcDouble = function(){
			return 2 * a;//closure      a
		};
		
		(function(){
			alert(gLanuageName);//global      gLanuageName
		})();

		return funcDouble;
	}
	var funcDouble = func();
	alert(funcDouble());
	alert(gLanuageName);//global     gLanuageName

</script>
 
다음은 위의 코드 실행 과정 에서 체인 검색 과정 을 분석 합 니 다.
1) alert(b);
먼저 현재 함수 역할 영역 에서 변 수 를 찾 습 니 다. b. 결 과 를 찾 고 되 돌려 줍 니 다.
2) return 2 * a;
우선 현재 함수 역할 영역 에서 변 수 를 찾 습 니 다. b 를 찾 지 못 했 습 니 다.그리고 부모 함수 역할 영역 에서 찾 았 습 니 다. 결 과 를 찾 았 습 니 다. 되 돌 아 왔 습 니 다.
3) (function(){alert(gLanuageName);})();
우선 현재 익명 함수 역할 영역 에서 변수 gLanuageName 을 찾 습 니 다.
그리고 윗 층 의 아버지 함수 역할 영역 에서 찾 았 지만 찾 지 못 했 습 니 다.
그리고 지난 층 의 global 역할 영역 에서 찾 아 보고 결 과 를 찾 아 되 돌려 줍 니 다.
 
분명히 위로 찾 는 단계 가 많 을 수록 시간 이 오래 걸린다.예 를 들 어 gLanuageName 을 찾 으 면 세 개의 역할 영역 을 찾 아야 변 수 를 찾 을 수 있 습 니 다.효율 을 높이 기 위해 서 는 현재 역할 영역 에서 자주 사용 되 는 변 수 를 현재 역할 영역 에 넣 습 니 다.예 를 들 어 window, undefined 등.이 예 에서 gLanuageName 을 func () {} 역할 영역 에 넣 고 역할 영역 을 찾 는 소 모 를 줄 일 수 있 습 니 다.
 
저 는 js 가 더 잘 하면 역할 영역 을 변수 로 만 들 수 있다 고 생각 합 니 다. 그러면 개발 자 들 이 역할 영역 을 직접 방문 하여 체인 검색 의 소 모 를 면제 할 수 있 습 니 다.예 를 들 어 global ['gLanuageName'], closure. funcmame. ['a'].브 라 우 저 에서 global 은 window 에 해당 합 니 다.
 
이해: 폐쇄 = 역할 영역 사유 성 + 역할 영역 지속 성
폐쇄 란 무엇 입 니까?누 군가 나 에 게 이렇게 물 을 때마다 나 는 마음 이 허전 하 다.이것 은 신기 한 개념 이 고 실패 의 개념 이다.
나의 이 해 는 폐쇄 = 작용 역 의 지속 성 + 작용 역 의 사유 성 이다.
 
작용 역 의 지속 성
함수 가 실 행 된 후에 도 역할 영역 에 있 는 대상 (변수 / 함수) 이 여전히 가지 고 있다 면 역할 영역 은 함수 의 실행 이 끝나 면 사라 지지 않 습 니 다.폐쇄 는 폐쇄 라 기보 다 는 작용 역 의 지속 성 이 라 고 할 수 있다.
 
역할 영역의 사유 성
사유 성 은 이해 하기 쉽 지만 사실은 JS 의 역할 영역 이 체인 검색 으로 결정 된다.체인 검색 방식 은 모든 함수 가 모든 역할 영역 에 접근 할 수 있 는 변 수 를 결정 합 니 다.아래 프로그램 에서 보 듯 이 scopeB, scopeC 는 ScopeA 를 체인 으로 찾 을 수 있 고 a 변 수 를 방문 할 수 있 습 니 다.그러나 scopeB 는 ScopeC 를 체인 으로 찾 을 수 없습니다. 즉, scopeB 함수 내부 에서 c 변 수 를 방문 할 수 없습니다. ScopeB 아래 의 변 수 는 ScopeC 에 보이 지 않 고 '개인' 입 니 다.
<script>
    function scopeA(){
          var a = 1;
          function scopeB(){
                var b =2;
                var _a = a;
                var getA = function(){
                      return _a;
                }
          }
          function scopeC(){
                 var c = 3;
            }
    }
</script>

 
폐쇄 = 작용 역 의 지속 성 + 
역할 영역의 사유 성 = > 모듈 패키지
지속 성 은 우리 가 특정한 변 수 를 지속 적 으로 보존 할 수 있 도록 해 준다. 사유 성 은 우리 가 변 수 를 특정한 함수 에 만 누설 할 수 있 도록 해 준다. 이 두 가 지 를 결합 시 켜 대상 을 대상 으로 하 는 '포장' 의 초석 을 구성 했다.폐쇄 는 실현 이다.
모듈 패키지 의 이기!
실천: 폐쇄 구조 모듈, 단일 공장 사용
다음은 Counter 의 예 를 들 어 보 겠 습 니 다.이 Counter 의 초기 값 은 0 이 고 add 를 통 해 + 1 을 실현 할 수 있 으 며 sub 를 통 해 - 1 을 실현 할 수 있 습 니 다. get 을 통 해 현재 값, 내부 상태 데이터 i 를 얻 을 수 있 습 니 다. 패 키 지 를 통 해 완벽 하 게 패 키 징 되 었 습 니 다. 외부 프로그램 은 sub, add, get 을 조작 할 수 있 는 것 을 제외 하고 i 자 체 를 조작 할 수 없 으 며 모듈 의 안전 과 안정 을 확보 합 니 다.
카운터 프로그램
<!DOCTYPE HTML>
<HTML>
 <HEAD>
  <TITLE>Counter</TITLE>
 </HEAD>

 <BODY>
<script>
		var oCounter = (function(){
			var i = 0;
			var get = function(){
				return i;
			}
			var add = function(){
				i++;
				return i;
			}
			var sub = function(){
				if(i-1<0){
					alert("counter is zero. Cannot perform subtraction.");
					return i;
				}
				i--;
				return i;
			}
			var o = {
				get : get,
				add : add,
				sub : sub
      			};
			return o;
		})();
		oCounter.add();
		alert(oCounter.get());
		oCounter.sub();
		alert(oCounter.get());
		oCounter.sub();
		alert(oCounter.get());
</script>
 </BODY>
</HTML>
  
패키지 정의 모듈 을 사용 하면 간단 한 방법 이 있 습 니 다.
1.  '개인' 역할 영역 으로 함 수 를 정의 합 니 다.
2.  함수 에서 var 를 사용 하여 '개인' 의 변수 / 함 수 를 정의 합 니 다.
3.  함수
'개인' 변수 / 함수 의 object 나 function 을 참조 합 니 다.
이 방식 에 따라 대부분의 모듈 화 수 요 를 만족 시 킬 수 있다.
 
Counter 프로그램 은 패 킷 을 닫 는 것 외 에 도 함수 가 되 돌아 오 는 대상 o. 대상 o 는 대외 적 으로 공 개 된 인 터 페 이 스 를 명확 하 게 묘사 하고 구체 적 인 실현 을 숨 겼 다 는 것 은 쉽게 교체 할 수 있다 는 것 을 의미한다. 만약 에 뒤의 수요 가 변화 하면 sub 는 i 를 마이너스 로 줄 일 수 있다. 그러면 우 리 는 sub 2 방법 을 추가 하여 실현 할 수 있다. 수정 대상 o 를 마이너스 로 할 수 있다.
var o = {
    get : get,
    add : add,
    sub : sub2
}; 

이렇게 해서 oCounter 를 사용 하 는 client 코드 는 바 꿀 필요 가 없습니다. 약간 JAVA 가 인터페이스 프로 그래 밍 을 하 는 맛 이 나 지 않 습 니까? o 는 사실 인터페이스의 구체 적 인 실현 역할 을 합 니 다. 모듈 을 설계 할 때 '인터페이스 대상' 을 잘 설계 하 는 것 이 좋 습 니 다. 나중에 모듈 이 바 뀌 더 라 도 모듈 을 사용 하 는 client 코드 를 바 꿀 필요 가 없습니다. 여 기 는 '인터페이스 대상' 만 제공 합 니 다."라 는 간단 한 사고방식 은 고정된 것 이 아니다.
 
만약 에 위의 코드 가 인 터 페 이 스 를 향 하지 않 고 대상 을 향 하지 않 는 다 고 생각한다 면 다음 코드 를 보고 단일 공장 모델 을 실현 하고 서로 다른 매개 변수 에 따라 서로 다른 Counter 를 되 돌려 주 었 습 니 다.
 
 
<!DOCTYPE HTML>
<HTML>
 <HEAD>
  <TITLE> Counter      </TITLE>
 </HEAD>

 <BODY>
<script>
		//    
		var oCounterFactory = (function(){
			var map = {};
			var oCounter = null;
			
			//    ,          Counter  ,couterType "Counter1"  "Counter2"
			function getSingletonCounter(couterName){
        			//    
				if(null == map[couterName]){
          				//        
					map[couterName] = eval('create' + couterName + '()');
				}
				return map[couterName];
			}

			//    1
			function createCounter1(){
				alert("create oCounter1");
				var i = 0;
				var get = function(){
					return i;
				}
				var add = function(){
					i++;
					return i;
				}
				var sub = function(){
					if(i-1<0){
						alert("counter is zero. Cannot perform subtraction.");
						return i;
					}
					i--;
					return i;
				}
				
				var o = {
					get : get,
					add : add,
					sub : sub
				};

				return o;
			}
			//    2
			function createCounter2(){
				alert("create oCounter2");
				var i = 0;
				var get = function(){
					return i;
				}
				var add = function(){
					i++;
					return i;
				}
				var sub2 = function(){
					i--;
					return i;
				}
				
				var o = {
					get : get,
					add : add,
					sub : sub2
				};

				return o;
			}
		
			var oCounterFactoryRtn = {
				getSingletonCounter : getSingletonCounter
			};
			return oCounterFactoryRtn;
		 })();
				
			
		alert("oCounter1 add : " + oCounterFactory.getSingletonCounter("Counter1").add());
		alert("oCounter1 add : " + oCounterFactory.getSingletonCounter("Counter1").add());
		alert("oCounter1 add : " + oCounterFactory.getSingletonCounter("Counter1").add());
		alert("oCounter2 add : " + oCounterFactory.getSingletonCounter("Counter2").add());
		alert("oCounter2 add : " + oCounterFactory.getSingletonCounter("Counter2").add());
		alert("oCounter2 add : " + oCounterFactory.getSingletonCounter("Counter2").add());
</script>
 </BODY>
</HTML>

  클 라 스 키 워드 는 없 지만 모듈 을 잘 패 키 징 하고 디자인 모드 까지 활용 할 수 있 습 니 다.
 
> > 다음 편  패키지 구조 모듈 (최적화 편) 사용 - Object - Oriented Javascript 의 4

좋은 웹페이지 즐겨찾기