Jak naśladować modyfikatory dostępu w JavaScript za pomocą biblioteki Prototype?

Pracuję z biblioteką prototypów już od jakiegoś czasu i czasami zdarza mi się, że chciałbym mieć wiele poziomów dostępu (publicznych, prywatnych i chronionych). Najbliższy, jaki dotąd osiągnąłem, jest następujący:

SampleBase = Class.create({
    /* virtual public constructor */
    initialize: function(arg1, arg2)
    {
        // private variables
        var privateVar1, privateVar2;

        // private methods
        var privateMethod1 = function() { }
        function privateMethod2() { }

        // public (non virtual) methods
        this.publicNonVirtual1 = function() { return privateVar1; }
        this.publicNonVirtual2 = function() { return privateVar2; }
    },
    // public methods (that cannot access privates)
    publicVirtual1: function() { /* Cannot access privates here. */ },
    publicVirtual2: function() { /* Cannot access privates here. */ }
});

To mniej niż idealne z kilku powodów:

Brak chronionego poziomuMogę mieć członków publicznych, którzy mogą uzyskiwać dostęp do członków prywatnych lub członków publicznych, którzy mogą być nadpisywani, ale nie są członkami publicznymi, którzy mogą uzyskać dostęp do członków prywatnych i być nadpisywani.Moje publiczne metody, które można przesłonić, nie są prototypowane.

Zrobiłem kilka poszukiwań, ale nie znalazłem niczego, co sugerowałoby, że mogę zrobić lepiej bez zmiany sposobu działania prototypu. Oto kilka ciekawszych linków:

Używając narzędzia Class.create Prototype do zdefiniowania prywatnych / chronionych właściwości i metodPrywatne metody JavaScriptCzłonkowie prywatni w JavaScriptPonownie z Wzorem Modułów - ujawnij coś światu

Widziałem, jak zasugerował, że możesz udostępnić akcesorium do moich publicznych metod wirtualnych, wykonując coś takiego:

Message = Class.create({
    initialize: function(message)
    {
        var _message = message;
        this.getMessage = function() { return _message; }
        this.setMessage = function(value) { _message = value; }
    },
    printMessage: function() { console.log(this.getMessage()); },
    appendToMessage: function(value) { this.setMessage(this.getMessage() + value); }
});

To nie będzie działać zgodnie z przeznaczeniem. Celem jest umożliwienie drukowania i dołączania do wiadomości spoza obiektu. Setter dostarczony do działania wirtualnej funkcji publicznej pozwala również na pełną kontrolę wiadomości. Można zmienić, aby wirtualna metoda była trochę więcej niż powłoka w następujący sposób:

Message = Class.create({
    initialize: function(message)
    {
        var _message = message;
        this._printMessage = function() { console.log(_message); }
        this._appendToMessage = function(value) { _message += value; }
    },
    printMessage: function() {this._printMessage(); },
    appendToMessage: function(value) { this._appendToMessage(value); }
});

Ta nowa wersja ogranicza dostęp publiczny do tej klasy, ale jest nieco zbędna. Nie wspominając, że appendToMessage jest nadpisywane w podklasie, osoba trzecia może nadal wywoływać _appendToMessage, aby uzyskać dostęp do oryginalnej metody, która nie jest dobra.

Mambardzo brudny pomysł, który doprowadzi mnie do siebie, ale jest puszką robaków, których wolałbym nie otwierać. Mogę to opublikować później, ale w międzyczasie ktoś ma sugestie dotyczące połączenia dwóch rodzajów metod publicznych w jeden użyteczny typ lub w jaki sposób zaimplementować chronionych członków.

EDYCJA: Podejrzewam brak informacji zwrotnych (pozabobinceNie przejmuj się komentarzem, oznacza to, że mam rację, że nie możesz tego wziąć dalej, ale myślę, że wyjaśnię trochę na wszelki wypadek. Nie sądzę, aby można było uzyskać coś bliskiego ochronie innych języków. Bardziej interesuje mnie wiedza, gdzie są granice i jak dokładne jest moje zrozumienie zasad. Uważam jednak, że byłoby interesujące, jeśli nie przydatne, gdybyśmy mogli uruchomić różne poziomy ochrony do tego stopnia, że ​​niepubliczni członkowie nie pojawią się w pętli for ... in (lub w Prototypach Object.keys, które używa for..in), nawet jeśli ludzie, którzy wiedzą, co robią, mogą nadal łamać zasady, robiąc takie rzeczy jak majstrowanie przy moich prototypach. Afterall, to jakbobince mówi „nie mają nikogo, kto mógłby winić tylko siebie”

Teraz skomentuj problem poruszony przezbobince:

Nawet jeśli stworzysz prawdziwe prywatne / chronione zmienne, nadal nie otrzymasz pełnej enkapsulacji, której wymagałaby skuteczna granica bezpieczeństwa. Zdolność JavaScript do manipulowania prototypami wbudowanych typów, których będą używać metody, daje atakującemu możliwość sabotowania metod.

Jest to jedno ograniczenie, które rozumiem i prawdopodobnie powinienem był wspomnieć powyżej. Jednak nie patrzę na to z punktu widzenia ochrony mojego kodu przed próbą włamania się do niego. Mam jednak kilka rzeczy, które mogą być warte uwagi (lub wymagają korekty, jeśli się mylę):

Tylko moi publiczni członkowie są w ten sposób narażeni.Jeśli moje publiczne metody wirtualne zostaną w ten sposób „skompromitowane”, metody „skompromitowane” nadal nie będą miały dostępu do członków prywatnych.Jeśli moi publiczni (nie wirtualni) członkowie są w ten sposób „narażeni”, w przeciwieństwie do oryginalnej wersji metody, „skompromitowana” wersja nie będzie miała dostępu do prywatnych wiadomości.O ile wiem, jedynym sposobem uzyskania dostępu do prywatnych członków za pomocą metod zdefiniowanych poza metodą inicjalizacji jest także skorzystanie z błędu w sposobie, w jaki niektóre przeglądarki obsługują połączenia eval.

questionAnswers(2)

yourAnswerToTheQuestion