2010-01-04 5 views
5

나는 "새로운"키워드와 "this"키워드의 범위와 관련된 모든 문제를 피하는 데 도움이되기 때문에 (모듈 패턴과 비슷한) 내 코드에 기능적 OOP 스타일을 사용하는 것을 선호합니다. 콜백.JavaScript의 기능적 OOP 스타일에 관한 질문

하지만 약간의 사소한 문제가 있습니다. 다음 코드를 사용하여 클래스를 만들고 싶습니다.

namespace.myClass = function(){ 
    var self = {}, 
     somePrivateVar1; 

    // initialization code that would call 
    // private or public methods 
    privateMethod(); 
    self.publicMethod(); // sorry, error here 

    function privateMethod(){} 

    self.publicMethod = function(){}; 

    return self; 
} 

문제는 아직 정의되지 않은 초기화 코드에서 공용 메서드를 호출 할 수 없다는 것입니다. 분명한 해결책은 init 메소드를 생성하고 "return self"라인 전에 호출하는 것입니다. 하지만 좀 더 우아한 해결책을 알고 있을까요?

또한이 패턴을 사용하여 상속을 어떻게 처리합니까? 다음 코드를 사용하지만 아이디어와 제안을 듣고 싶습니다.

namespace.myClass2 = function(){ 
    var self = namespace.parentClass(), 
     somePrivateVar1;    

    var superMethod = self.someMethod; 
    self.someMethod = function(){ 
    // example shows how to overwrite parent methods 
    superMethod(); 
    }; 

    return self; 
} 

편집.

+0

일반적으로 언어에서 제공하는 기술을 사용하지 않는 것이 좋습니다. 그건 당신이'new'를 우회해서는 안된다는 것을 의미합니다. 자바 스크립트로 끝난 것입니다. 아마도이 특별한 언어에서 가장 좋은 방법 일 것입니다. –

+0

전화를 걸기 전에 맨 위의 메서드를 정의 할 수없는 이유는 무엇입니까? –

+0

Gs, private 멤버를 사용하여 객체를 만드는 데 클로저를 사용하는 것은 언어에서 제공하는 기술이라고 생각합니다. Douglas Crockford조차도 그것을지지합니다. 나는 또한 약간의 성능 테스트를하기 전에, 그리고 적은 양의 물체에 대해서는별로 중요하지 않습니다. (http://valums.com/b/) 그러나 나에게 그것은 코드를 더 깨끗하게 만든다. –

답변

0

나는 거의 모든 의견에 동의하거나 지금까지 제공 한 대답 만 더 팀의 대답은 하나의 조치를 취할 - 당신이 정의되기 전에 메소드를 호출 싶어 왜 그가 의문을 제기하지만, 어쨌든 솔루션을 제공, 반면에 나는 을 정의하기 전에을 호출해서는 안된다고 제안하는 반면 (정의하기 전에 메서드를 호출하거나 적어도이를 좋은 연습으로 간주하는 언어를 모르는 경우) 대략적인 방법은 다음과 같습니다.

namespace.myClass = function(){ 
    //declare private vars (and self) first 
    var self = {}, 
     somePrivateVar1; 

    //then declare private methods 
    function privateMethod(){} 

    //then public/privileged methods 
    self.publicMethod = function(){}; 

    // THEN (and only then) add your 
    // initialization code that would call 
    // private or public methods 
    privateMethod(); 
    self.publicMethod(); // no error any more 

    //then return the new object 
    return self; 
} 

왜 이것이 작동하지 않는 특별한 이유가 있습니까?

+0

고맙습니다.이 작업은 정상적으로 수행 될 것입니다. 그러나 매우 일반적인 방식으로 생성자를 맨 위에두고 싶습니다. 다른 프로그래머들의 습관을 깨고 싶지는 않습니다. –

1

몇 가지 질문은 왜 당신을로, 나에게 발생합니다 OOP의이 스타일을 선택하는 이유, 당신은 다음과 같은 질문으로 볼 수 있습니다 무엇을 요구하는 사람들을 위해 new 연산자를 피하고 왜 정의되기 전에 함수를 호출해야하는지. 그러나 그것들을 제쳐두고 떠나는 것은 다음과 같은 것입니다.

namespace.myClass = function(){ 
    var somePrivateVar1; 
    var self = {}; 

    // initialization code that would call 
    // private or public methods 
    privateMethod(); 
    publicMethod(); 

    function privateMethod(){} 
    function publicMethod(){} 

    self.publicMethod = publicMethod; 
    return self; 
} 
+0

감사합니다.이 방법의 문제점 중 하나는 클래스 내부의 현재 개체에 대한 참조가 없다는 것입니다. 그러나 필자의 예에서는 자체 변수 인 ex를 사용하여 객체 자체를 다른 함수에 전달할 수있었습니다. someFunctionThatRegistersAnObject (self); –

+0

귀하의 답변을 투표하려했지만 stackoverflow에 "이 답변을 편집하지 않으면 변경하기에는 너무 투표가 오래되었습니다."라는 오류가 표시됩니다. 그게 버그 야? –

+0

@valums : 답변이 귀하의 의견을 반영하도록 변경되었습니다. SO 오류에 대한 확신이 없지만 답변을 편집 한 지금 투표를 변경할 수 있어야합니다. –

0

이것은 내가 질문에서 언급 한 해결책입니다. 귀하의 의견을 환영합니다.

namespace.myClass = function(){ 
    var self = {}, 
     somePrivateVar1; 

    function init(){ 
    privateMethod(); 
    self.publicMethod(); 
    } 

    function privateMethod(){} 
    self.publicMethod = function(){}; 

    init(); 
    return self; 
} 
+1

그게 효과가있을 것입니다, 당신이 맨 처음에 초기화 코드를 가지고 있다면, 당신의 방법 중 하나를 선언하기 전에 제가 갈 수있는 유일한 방법 일 것입니다. 나의 유일한 의견은 이것이 당신이 요구 한 것인데 "우아함"이 아니라는 것이다. 그러나 나의 * 개인적인 견해는 당신이 어떻게 "보기"를 원하는지에 대한 당신의 기준이 어쨌든 우아하지 않다는 것이다 - 그래서이 기준 내에서, 당신이 가지고있는 것이 아마도 가장 좋은 해결책 일 것입니다. – Graza

2

당신은 당신이 원하는 방법으로 클래스를 선언과 함께 당신을 도울 것입니다 Zet.js 라이브러리를 사용할 수 있습니다.