Візьміть будь-які з рішень , які слідують Крокфорд в приватному або привілейований шаблоні. Наприклад:
function Foo(x) {
var y = 5;
var bar = function() {
return y * x;
};
this.public = function(z) {
return bar() + x * z;
};
}
У будь-якому випадку, коли зловмисник не має права "виконати" у контексті JS, він не має доступу до будь-яких "публічних" чи "приватних" полів чи методів. У випадку, якщо зловмисник має такий доступ, він може виконати цей однолінійний:
eval("Foo = " + Foo.toString().replace(
/{/, "{ this.eval = function(code) { return eval(code); }; "
));
Зауважте, що наведений вище код є загальним для всіх конфіденційності типу конструктора. Деякі рішення тут не вдасться, але повинно бути зрозуміло, що майже всі рішення на основі закриття можуть бути порушені, як це, з різними replace()
параметрами.
Після цього будь-який об'єкт, створений за допомогою new Foo()
, матиме eval
метод, який можна викликати для повернення чи зміни значень або методів, визначених у закритті конструктора, наприклад:
f = new Foo(99);
f.eval("x");
f.eval("y");
f.eval("x = 8");
Єдина проблема, яку я бачу з цим, що вона не працюватиме у випадках, коли є лише один екземпляр, і він створений при завантаженні. Але тоді немає підстав насправді визначати прототип, і в такому випадку зловмисник може просто відтворити об'єкт замість конструктора до тих пір, поки у нього є спосіб передачі тих же параметрів (наприклад, вони постійні або обчислюються з наявних значень).
На мою думку, це в значній мірі робить рішення Крокфорда марним. Оскільки "конфіденційність" легко порушується і недоліки його рішення (знижена читабельність та ремонтопридатність, зниження продуктивності, збільшення пам'яті) робить метод, заснований на прототипі "без конфіденційності", кращим вибором.
Зазвичай я використовую провідні підкреслення для позначення __private
та _protected
методів та полів (стиль Perl), але ідея наявності конфіденційності в JavaScript просто показує, наскільки це неправильно зрозуміла мова.
Тому я не згоден з Крокфордом крім його першого речення.
Отже, як отримати реальну конфіденційність у JS? Покладіть все, що потрібно, щоб бути приватним на стороні сервера і використовувати JS для здійснення AJAX-дзвінків.