2010-07-15 2 views
2

모듈 패턴이나 공개 모듈 patten과 같은 '클래스'유형 JavaScript 함수를 작성하기 시작했습니다. 이것은 'new'의 사용을 피하고 어느 기능이 하나의 장소에서 공개되는지를 정의 할 수있게 해줍니다. 그러나이 패턴으로 공용 데이터 멤버를 사용하고 액세스하는 방법을 볼 수 없었습니다.JavaScript 생성자 함수에서 객체를 반환 할 때 ('new'를 피할 때) public 멤버를 구현하려면 어떻게해야합니까?

아래의 'id'멤버는 myobj.getId()를 통해 액세스 할 수 있지만 myobj.id는 정의되지 않습니다.

function setup(){ 
    var myobj = MyObject(); 
    myobj.initialize(); 
    alert(myobj.getId()); // returns 3, as expected 
    alert(myobj.id); // returns undefined 
} 
function MyObject(){ 
    var id; 
    function initialize(){ 
     //do some stuff that initializes data including... 
     id = 3; 
    } 
    return{ 
     initialize:initialize, 
     id:id, 
     getId:function(){ return id;} 
    } 
} 

initialize()에 설정된 값을 반환하도록 myobj.id를 작동시킬 방법이 없습니까?

+1

, 대문자로 시작하는 함수를 생성자 (클래스 이름과 유사)'new'와 함께 사용하기위한 것입니다. 이와 같은 팩토리 함수는 소문자로 시작해야합니다. – jasongetsdown

+1

@ jasongetsdown Javascript convention? 절대 들어 본적이 없어! –

+0

@Josh 나는이 진술이 나타내는 것을 궁금해합니다 ... – galambalazs

답변

1

변수 id은 기본적으로 undefined으로 설정되어 있으며 유형은 undefined이기도합니다. 이제, 정의되지 않은 유형이 프리미티브 유형이기 때문에 반환 된 객체에서의 할당은 참조가 아닌 값 할당이됩니다. 따라서 obj.id은 인스턴스에서 undefined이되고 생성자 함수의 변수는 id이 아닙니다.

이제 initialize은 생성자 함수에서 id 변경되며, getId 같은 id을 반환하지만 obj.idundefined 객체 속성을 참조합니다.

function MyObject(){ 
    // initialize is used as a public function so 
    // this will always refer to the current instance 
    function initialize(){ 
     this.id = 3; 
    } 
    return { 
     // no need to define id here it will 
     // report undefined on access by default 
     initialize: initialize, 
     getId:function(){ return this.id; } 
    } 
} 

Run 전체 물건 가 예상대로 작동 볼 수 있습니다.

+0

삭제 된 응답에 표시 한 태도가 모두 필요하지 않지만 내 질문에 답변 해 주셨습니다. – pc1oad1etter

+0

내 대답은 당신을 더 혼란스럽게 만들려하지 않는 것이 었습니다. :) 누군가가 그의 오개념을 고수하고 심지어 퍼뜨릴 때, 당신은 무엇을 할 것입니까? 나는 문제를 개괄하려했지만 그는 듣지 않았다. 보시다시피 그는 마침내 실현하고 그의 대답을 삭제했습니다. 힘든 감정은 다시 한번, 정확성에 관한 것이지 사람들을 혼란스럽게하는 것이 아닙니다. – galambalazs

3

당신의 문제는 당신이 폐쇄를 이용하지 않는다는 것입니다. id:id 줄은 반환 할 개체 리터럴의 멤버로 새 변수를 만듭니다. 기본값은 undefined입니다. 그런 다음 동일한 변수 id을 다시 undefined에 할당합니다.

또한 모듈은 팩토리 기능이 아닌 단일 객체 인스턴스입니다.

var myModule = (function(opts) { 
    var foo = opts.foo || 0, //private variables with default values 
     bar = opts.bar || 0, // if none are passed in 

     product = function() {  //private method 
      return (foo * bar); 
     }; 

    return { 
     getFoo : function() { //public methods 
      return foo; 
     }, 
     fooTimesBar : function() { 
      return product(); 
     } 
    } 
})({ 
    foo : 5,     //options object 
    bar : 7 
}); 

모듈 패턴의 핵심 변수를 선언하고 폐쇄을 통해 해당 변수에 대한 접근 권한이있는 개체를 반환 익명 함수를 실행 자체이다 : 이런 식으로 뭔가를 시도하십시오.

전달되는 일부 옵션이있는 개체 리터럴을 포함하는 마지막 괄호는 함수를 실행 한 다음 개체를 반환하고 myModule에 할당합니다.

반환 된 개체의 멤버로 선언 된 모든 항목은 공개적으로 액세스 할 수 있습니다. 반환 된 객체의 코드는 함수가 반환 된 후에도 폐쇄를 통해 익명 함수에 정의 된 변수에 액세스 할 수 있습니다. 익명 함수로 선언 된 변수는 효과적으로 비공개입니다. 함수 외부의 코드는 반환 된 객체에서 제공되는 메서드를 제외하고는 해당 객체를 처리 할 수 ​​없습니다.

모든 것이 단일 개체 인스턴스 myObject이됩니다. 하나 이상의 모듈을 정의 할 수있는 모듈은 하나만 만들 수 있습니다. 그러나 비슷한 방법을 사용하여 공장 기능을 만들 수도 있습니다.

+0

+1 좋은 예와 설명 –

+0

@jasongetsdown - 이것이 싱글 톤 모듈이 아니라는 것을 깨달았지만, 결국이 객체 리터럴을 반환하는 패턴을 설명하는 단어가 무엇인지 모르겠다. 모듈 패턴의 설명에 사용됩니다. – pc1oad1etter

+0

@jasongetsdown 내가 명확하게 표현하지는 못했지만 "모듈 패턴이나 모듈 패튼과 같은 '클래스'유형 JavaScript 함수를 작성하기 시작했습니다."나는 객체를 반환하는 스타일을 사용한다는 의미였습니다. 결국 모듈 및 모듈 모듈 패턴에서 본 것과 같습니다. 그래서 저는 실제로 당신이 묘사 한 것처럼 모듈을 찾고 있지 않습니다. 저는 그것을 모듈로 사용했으며,이 부분을 너무 좋아해서 이것을 생성자처럼 사용하고 싶었습니다. 그래서이 질문에 나를 이끌었습니다. 감사. – pc1oad1etter

0

익명 객체 대신 캐시 된 객체를 반환하여이 문제를 해결하고 계시 모듈 패턴의 구문 설탕을 유지할 수 있습니다.

예 : 관례

NAMESPACE.Module = (function() { 

    //All public members go on api 
    var api = {} 
    api.id = 3; 

    //Private members 
    var self, 
     foo, 
     bar; 


    /** 
     @public 
    */ 
    api.init = function() { 
     self = this; 
     console.log(this); //NAMESPACE.Module 
    } 


    /** 
     @private 
    */ 
    function _privateFunction() { 
     console.log(self); //NAMESPACE.Module 
    } 

    return api; 
}()); 
관련 문제