Как имитировать модификаторы доступа в JavaScript с помощью библиотеки Prototype?
мы работаем с библиотекой прототипов уже некоторое время и время от времени желаем, чтобы у меня было несколько уровней доступа (публичный, частный и защищенный). Ближайший яМы дошли до следующего:
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. */ }
});
Это менее чем идеально по нескольким причинам:
Нет защищенного уровняУ меня могут быть открытые участники, которые могут получить доступ к закрытым членам или открытым членам, которые могут быть переопределены, но не открытые участники, которые могут получить доступ к закрытым членам и могут быть переопределены.Мои открытые методы, которые могут быть переопределены, не являются прототипами.мы сделали некоторые поиски, но укрылисьЯ не нашел ничего, что подсказывало бы, что я могу добиться большего успеха, не меняя принцип работы прототипа. Вот'Вот некоторые из наиболее интересных ссылок:
Использование Prototype ’s Class.create для определения частных / защищенных свойств и методовЧастные методы JavaScriptЧастные пользователи в JavaScriptСнова с шаблоном модуля - открой что-нибудь мирумы видели, что вы можете предоставить средства доступа для моих публичных виртуальных методов, используя что-то вроде этого:
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); }
});
Это явно не будет работать как задумано. Цель состоит в том, чтобы разрешить только печать и добавление к сообщению снаружи объекта. Установщик, обеспечивающий работу виртуальной общедоступной функции, также позволяет полностью контролировать сообщение. Его можно изменить, чтобы сделать виртуальный метод немного больше, чем оболочка, следующим образом:
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); }
});
Эта новая версия ограничивает публичный доступ для этого класса, но несколько избыточна. Не говоря уже о том, что appendToMessage переопределено в подклассе, третья сторона может по-прежнему вызывать _appendToMessage для доступа к исходному методу, который не годится.
У меня естьочень грязный Идея, которая приблизит меня, но это червь яЯ предпочитаю не открывать. Я могу опубликовать это позже, но в то же время у кого-нибудь есть предложения по объединению двух типов открытых методов в один полезный тип или о том, как реализовать защищенные члены.
РЕДАКТИРОВАТЬ: я подозреваю отсутствие обратной связи (за исключениемbobince»с некомментируйте) я имею в виду, что вы правыне бери дальше, но я думаю, чтоуточню немного на всякий случай. Я неЯ думаю, что возможно получить что-то близкое к защите других языков. Я'Мне больше интересно знать, где лежат границы и насколько точно мое понимание вовлеченных принципов. Однако я думаю, что было бы интересно, если не полезно, если бы мы могли привести в действие различные уровни защиты до такой степени, чтобы непубличные участники неОн не будет отображаться в цикле for ... in (или в Prototypes Object.keys, который использует for..in), даже если люди, которые знают, что они делают, могут нарушать правила, например, работая с моими прототипами. В конце концов, это какbobince говорит " им некого обвинять, кроме самих себя
Теперь, чтобы прокомментировать проблему, поднятуюbobince:
Даже если вы сделали настоящие закрытые / защищенные переменные, это все равноЯ не получу полную инкапсуляцию, которая потребуется для эффективной границы безопасности. JavaScript»Способность работать с прототипами встроенных типов, которые будут использовать ваши методы, дает злоумышленнику возможность саботировать методы.
Это одно ограничение, которое я понимаю, и я, вероятно, должен был упомянуть выше. Однако я не смотрю на это с точки зрения защиты своего кода от того, кто пытаетсявзломать» Это. Тем не менее, у меня есть несколько вещей, которые стоит отметить (или нуждающихся в исправлении, если я ошибаюсь):
Только мои публичные члены уязвимы в этом смысле.Если мои общедоступные виртуальные методыскомпрометированы» таким образом, то "скомпрометированы» методы по-прежнему не будут иметь доступа к закрытым членам.Если мои публичные (не виртуальные) участникискомпрометированы» Таким образом, в отличие от оригинальной версии метода, "скомпрометированы» версия не будет иметь доступа к приватным членам.Насколько я знаю, единственный способ получить доступ к закрытым членам с помощью методов, определенных вне метода initialize, - это воспользоваться ошибкой в том, как некоторые браузеры обрабатывают вызовы eval.