2012-04-25 5 views
0

자바 스크립트 및 모듈 패턴을 배우고 있지만 코드에서 실수를 범했지만이 패턴에 대한 개념이 잘못 되었음이 틀린 것으로 입증되었습니다. 내 기본 코드는 다음과 같다 : 자바 스크립트 모듈 패턴 변수 범위

(function(window,$){ 

//global menu object 
var menu = (function(){ 

    //menu tab component 
    var tab = (function(){ 

     //public properties 
     var tab = { 
      init:doStuff 
     } 

     //private properties 
     function doStuff(){ 
      alert("initialising Tab") 
     } 

     //return public properties 
     return tab; 
    })(); 

    //menu curtain component 
    var curtain = (function(){ 

     //public properties 
     var curtain = { 
      init:doStuff 
     } 

     //private properties 
     function doStuff(){ 
      alert("initialising Curtain") 
     } 

     //return public properties 
     return curtain; 
    })(); 

    //menu content component 
    var content = (function(){ 

     //public properties 
     var content = { 
      init:doStuff 
     } 

     //private properties 
     function doStuff(){ 
      alert("initialising Content") 
     } 

     //return public properties 
     return content; 
    })(); 

    //public properties 
    var menu = { 
     init:initialiseMenu 
    } 

    //private properties 
    function initialiseMenu(){ 
     //initialise each component of the menu system 
     tab.init(); 
     curtain.init(); 
     content.init(); 

    } 

    //final menu object 
    return menu; 
})(); 

window.menu = menu; 
})(window,jQuery); 

이 내 페이지가로드 코드라고 그런 경우 :

menu.init(); 

그것은 순서로 경고를 제공합니다

initialising tab 
initialising curtain 
initialising content 

내가 예상대로. 나는 콘텐츠 구성 요소를 변경한다면 다음과 같이 할 수 있습니다 :

//menu content component 
    var content = (function(){ 

     //public properties 
     var content = { 
      init:doStuff 
     } 

     //private properties 
     function doStuff(){ 
      alert("initialising Content") 
     } 

     //CHECK ACCESS TO PREVIOUS VARIABLES 
     curtain.init(); 

     //return public properties 
     return content; 
    })(); 

은 순서대로 알림을 제공합니다

initialising curtain 
initialising tab 
initialising curtain 
initialising content 

그래서 나는 년후에도 커튼 변수에 액세스 할 수 있는지 참조 인수로 모듈에 전달되지 않았습니다. 각 모듈에는 자체 포함되어 있다고 생각했지만, 사실이 아니라는 것을 발견했습니다. 모듈을 만들 변수가 필요한 변수에만 액세스 할 수 있습니까? 특히 내 예를 들어 도움이 될 것입니다, Dan 감사합니다.

답변

2

각 모듈은 자체적으로 포함되지 않으며 오히려 모듈을 만든 상위 집합 인 새 범위를 만듭니다. Javascript에서 새 범위를 정의하는 유일한 것은 function 문입니다. 새로운 스코프 내에서 같은 이름의 변수로 덮어 쓰지 않으면 외부 스코프의 모든 것이 표시됩니다. 내부 범위의 아무 것도 그 바깥쪽에 보이는 것은 없습니다.

var global; 
function outer() { 
    var outerVar; 

    function inner() { 
     var innerVar; 

     // global, outerVar, and innerVar are visible 

    } 
    function inner2() { 
     var inner2var, outerVar; 

     // global and inner2var are visible 
     // outerVar hides the previous outerVar, which is no longer accessible 

    } 

    // global and outerVar (the first one) are visible 

} 

귀하의 기능이 자체 실행한다는 사실은 차이를 만들지 않습니다. 바깥 쪽 범위에 만들어진 것은 그 안의 다른 영역 변수를 대체하지 않는 한 내부 범위에서 볼 수 있습니다.

내부 범위와 관련하여, 외부에서 생성 된 항목은 모두 글로벌 항목과 동일합니다. (그리고 전역 변수는 기본 범위 인 브라우저의 "창"에 만들어집니다.)

단방향 유리 뒤에있는 것처럼 내부 범위를 생각할 수 있습니다. 당신은 여전히 ​​세계의 모든 것을 볼 수 있지만 세상은 당신을 볼 수 없습니다. 그리고 항상 단방향 유리를 차단하여 더 이상 볼 수 없도록 선택할 수 있습니다. 그러나 아무것도 볼 수 없게됩니다.

+0

이 여전히 ES6이 출시 된 현재입니까? –

+0

예, ES6은 ES5의 상위 집합입니다. 'let'과 같은 새로운 범위 구조가 있지만이 코드는 여전히 유효합니다. –

0

현재 기능 범위는 포함 된 범위를 볼 수 있습니다. 따라서 콘텐츠는 커튼이 포함 된 메뉴의 모든 변수에 계속 액세스 할 수 있습니다.

0

각 개체에서 '반환'을 호출하면 각 구성 요소의 내부 '공용 속성'개체 인 반환 값이 구성 요소 변수에 할당되기 때문에 이러한 상황이 발생합니다.

var tab = (function(){ 

    //public properties 
    var tab = { 
     init:doStuff 
    } 

    //private properties 
    function doStuff(){ 
     alert("initialising Tab") 
    } 

    //return public properties 
    return tab; 
})(); 

여기서는 실행중인 익명 기능의 결과를 원래 변수 '탭'에 할당합니다. 이 경우 목적은 다음과 같습니다

var tab = { 
     init:doStuff 
    } 

당신이 함수의 실행의 끝에서이 개체를 반환하기 때문이다.

당신이 무엇을했는지 알아 보려면 함수의 범위 내에서 변수에 액세스하는 'public'수정 자 함수가있는 객체를 반환하십시오. 함수 내에서 생성 된 변수는 해당 함수 또는 해당 범위 내의 함수에만 범위를 가지므로 효과적으로 비공개가됩니다 (Javascript는 기능적으로 범위가 지정됨). 다음 예제 코드와 함께 당신을 도울해야합니다

var tab = (function(){ 

    //public properties 
    var PublicProperties = { 
     init:doStuff, 
     modifyPrivateVar: function(value){ 
      this.somePrivateVariable = value; 
     } 
    } 

    //private variables/properties 
    var doStuff = function(){ 
     alert("initialising Tab") 
    } 

    var somePrivateVariable = 'private!'; 

    //return public properties 
    return PublicProperties; 
})(); 

이제 변수 '탭'할당 할 값이 익명 함수의 실행에 의해합니다 (PublicProperties 객체)이 돌아왔다. 함수 "init"및 "modifyPrivateVar"에 액세스 할 수 있지만 "doStuff"를 호출하거나 "somePrivateVariable"을 직접 변경할 수는 없습니다. 이는 수정 자 함수를 통해 변수를 변경할 수는 있지만 직접 액세스 할 수는 없기 때문에 효과적으로 해당 변수를 비공개로 만들 수 있음을 보여줍니다.

"init"함수를 생성자로 호출하려면 구성 요소의 익명 함수 실행 실행 내에서 "생성자 함수"를 실행하거나 코드를 인라인으로 작성하고 실행하면됩니다 구성 요소의 익명 함수가 실행될 때 .... 그렇지 않으면 init 함수와 관련된 아무 것도 반환하지 않아야합니다.이 함수가 private 인 경우 안전한 방법으로 객체를 수정/활성화하는 데 사용할 수있는 함수 만 반환하십시오.

관련 문제