2009-06-25 1 views
7

에 private 멤버에 액세스하는 데, 나는더 나은 방법은 자바 스크립트의 <a href="http://javascript.crockford.com/prototypal.html" rel="noreferrer">prototypical inheritance model</a>에 비트를 읽은 후 자바 스크립트

var Some_Class = function() { 
    (function() { 
     // constructor 
    }).call(this) 
} 
Some_Class.prototype.public_method = function() { 
}; 

var Some_Class = function() { 
    this.public_method = function() { 
    }; 
    (function() { 
     // constructor 
    }).call(this) 
} 

에서 클래스를 구성하는 내 스타일을 변경 좋은 방법이지만 더 이상 공용 메서드에서 개인 메서드에 액세스 할 수 없습니다.

var Some_Class = function() { 
    var private_member = 'whatever'; 

    (function() { 
     // constructor 
    }).call(this) 
} 
Some_Class.prototype.public_method = function() { 
    return private_member; // not possible 
}; 

기사 here (폐쇄 만든 생성자)를 통해 읽은 후, 나는이 일의 단점은 무엇인가, 그러나이

var Some_Class = function() { 
    var private_member = 'whatever', 

    private_method = function(_some_value) { 
     // private method implementation 
    }; 

    if(!arguments.callee.prototype.public_method) { 
     arguments.callee.prototype.public_method = function() { 
      private_method.call(this, private_method); 
     }; 
    } 

    (function() { 
     // constructor 
    }).call(this) 
} 

나왔다! 또는 public 메서드에서 private member에 액세스하려는 경우이 작업을 수행하는 더 좋은 방법이 있습니까?

답변

10

개인 변수/함수를 시뮬레이트하기위한 함수 범위 변수 및 클로저의 사용은 자바 스크립트 공동체에서 잘 정립 된 관용구입니다. 변수가 진정으로 비공개 인 경우이 방법에 단점이없는 것으로 나타났습니다 (일부 브라우저/호스트에서 성능있는 코드가 생성되는 클로저 수에주의해야한다고 주장하기는하지만).

private_method (및 해당 환경)는 모든 객체에서 공유됩니다. public_method 클로저는 객체가 처음 생성 될 때만 만들어지기 때문에 (그리고 생성 된 객체의 내부 프로토 타입을 설정하는 생성자의 prototype 속성에 바인딩되기 때문에) chain) - private_method는 처음 생성 된 private_method 만 사용합니다.

 
    var global = 1; 

    var Some_Class = function() { 
    var private_method = 'whatever'; 
    var now = ++global; 
    print("outer now: " + now); 
    private_method = function(_some_value) { 
     // private method implementation 
     print("inner now: " + now); 
    }; 

    if(!arguments.callee.prototype.public_method) { 
     arguments.callee.prototype.public_method = function() { 

      private_method.call(this, private_method); 
     }; 
    } 

    (function() { 
     // constructor 
    }).call(this) 
} 

new Some_Class().public_method(); // outer now: 2, inner now: 2 
new Some_Class().public_method(); // outer now: 3, inner now: 2 
new Some_Class().public_method(); // outer now: 4, inner now: 2 

당신이 원하는 무엇을 확실 : 여기

은 무슨 일이 일어나고 있는지 설명하는 데 도움이 될 몇 가지 예제 코드인가?

private_method가 둘러싸는 객체의 상태를 참조 할 필요가 없다면, 내가하는 일을하는 데 거의 도움이되지 않습니다. (난 내 개체를 만듭니다 '새'를 사용하는 경우) 나는 보통 무엇을

는 다음과 같습니다 :

 
function MyClass() { 
    var private_var = 1; 
    function private_func() 
    { 

    } 
    this.public_func = function() 
    { 
    // do something 
    private_func(); 
    } 
    this.public_var = 10; 
} 

var myObj = new MyClass(); 

이 방법의 단점은 때마다 당신이를 통해 객체를 생성한다는 것입니다 '새로운' 모든 클로저를 다시 만듭니다. 그러나 내 프로파일 작성자가이 디자인 선택을 최적화해야한다고 말하지 않으면 단순 성과 명확성을 선호합니다.

 
    (function() { }).call(this); // call the constructor 

왜 당신이 당신의 생성자에서 별도의 범위를 만드는 :

또한 나는 중 다음을 수행의 코드에 혜택을 표시되지 않는 이유는 무엇입니까?

+0

덕분에 ... 난 여전히 개체 모델에 매우 익숙하지 오전 PHP/자바/기타 OOP의 OOP 코드와 유사한 내 코드를 만들기 위해 원하는 때문에 아마 추측 프로그래밍 언어 – Jeffrey04

11

내 대답은 대답이 아닙니다 : JavaScript에 private 액세스가 내장되어 있지 않지만 괜찮습니다. YAGNI입니다. 충분히 좋은

function Some_Class() { 
    this._private_member = 'whatever'; 
} 

Some_Class.prototype._private_method = function() { 
}; 

: 내 코드에서 private 회원을 방법은 다음과.그것은 private의 유일한 목적으로부터 자신을 보호하는 것입니다 때 ... 자신 남이에게 정말 가치가 없어.

는 (나는이 자신은 "그것 가치가 없어, 그것을 나사"라는 마지막으로 당신이하는 것처럼, 폐쇄 및 프로토 타입의 모든 순열과 장난, 많은 시간을 소비 한 말.)

+0

나는 동의한다. 그것을 지원하지 않는 가짜 개인 접근을 강요하는 것은 대개 UR을하는 것을 의미합니다. – Triptych

+0

@Triptych - 내가 일반적으로 당신이 원하는 것을 할 수있는 잘 설계된 언어 싸움을해야하는 경우, 당신은 정말 당신의 디자인을 재고해야한다고 동의하면서. 그러나,이 경우, 기능 범위 변수 및 폐쇄를 통해 시뮬레이션 개인 액세스가 많은 잘 설립 노련한 자바 스크립트 프로그래머에 의해 자연 자바 스크립트 관용구로 승인된다. –

+0

+1 +1 부작용은 많은 IDEs 코드 어시스트를 깨뜨리는 경향이 있습니다. –

1

당신이하지 않은 경우 이미 등 공용 기능 내에서 개인 메소드와 변수에 액세스 할 수 있도록이 JavaScript Module Pattern 봐,뿐만 아니라 싱글 프로토 타입

+0

: DI는 전에 그것에 대해 읽었습니다. 그저 어떤 이유로 싱글 톤 패턴을 좋아하지 않고 다른 방법을 찾고 싶습니다. – Jeffrey04

0

작품을 가지고 그렇게. 이 서브 클래스 시간이 때 문제는 내 서브 클래스는 존 Kugelman를 반향 음부

+1

자바의 하위 클래스조차도 '슈퍼'의 비공개 설정에 액세스 할 수 없습니다. – lcn

1

에 액세스 할 수 없습니다, : 그것은 자바 스크립트 개인 회원을 생성하는 것은 불가능하다. 그것으로 살아라. 이 같은 인클로저를 작성해도 :

function SomeClass() { 

    var _private = 0; 
    this.public_acessor = function() {return _private}; 
} 

모든 사용자는 여전히 쓸 수 있습니다 : 결국

SomeClass._not_private_anymore = 1; 
SomeClass.public_acessor = function() {return this._not_private_anymore}; 

, 당신은 당신이 선언 동일하게 모든 public 멤버를 믿을 수 없다. 누군가 코드를 깨뜨린다면 그는 그렇게 할 것입니다! 다른 사용자가 유용하기 때문에 코드를 해독하지 않습니다. 두 번째 질문에 대해, 그를 지우는

관련 문제