Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 13.07.2020, 16:10
Интересующийся
Отправить личное сообщение для Launder Посмотреть профиль Найти все сообщения от Launder
 
Регистрация: 25.04.2019
Сообщений: 19

Ограничения getter (setter)
Решил запаролить доступ к объекту (как пример "оболочки" на объект), без использования прокси.
Попробовал такой нехитрый способ:
let obj =
     {
         a: 145,
         b: 146,
         c: 147
     }

let pass = 'lex';

let passObj =
               {
                  get p()
                         {
                            return prompt('password?') == pass ? obj : alert('access denied');
                         }
               }
     

obj = passObj.p; //перезаписываем ссылку на объект

alert( obj.a );
alert( obj.b );
alert( obj.c );


Радостно обнаружил, что пароль работает только один раз при присвоении, затем видимо, результат записывается в passObj.p, а затем обратно в obj. Немного согрелись
При этом если мы в геттере для passObj.p будем возвращать примитив, например число, то к нему будет нормальный доступ по паролю.
Читаю MDN:
1. нуль параметров (понятно)
2. Геттер не должен появляться в объектном литерале вместе с другим get (ок) или через ввод данных для того же свойства (а почему же тогда запрос пароля, для примитива работает?)
3. Он может иметь идентификатор, который является либо числом, либо строкой; - вот тут непонятно, имеется в виду, что результатом работы геттера может быть либо число, либо строка?...
В спецификации (искал "getter") я немного запутался, соотнести указанные там шаги с какими-то реальными операциями у меня не получилось...
Например, как расшифровать запись:
Код:
2. Let desc be ? O.[[GetOwnProperty]](P).
и где может быть общая информация, как выше в MDN, к сожалению, не совсем понятно...
В общем, хотелось бы понять, может ли геттер возвращать объект.
Понять получше, что он вообще может...
Ну и как бонус, попробовать найти альтернативу прокси в замыкании...
Ответить с цитированием
  #2 (permalink)  
Старый 13.07.2020, 18:43
Профессор
Отправить личное сообщение для Nexus Посмотреть профиль Найти все сообщения от Nexus
 
Регистрация: 04.12.2012
Сообщений: 3,703

Вы что-то очень странное написали, чтобы понять что у вас в коде происходит нужно пару минут (мне, во всяком случае).
Зачем вам подобная конструкция - непонятно.

"Запаролили" свойства объекта и сразу же к ним обращаетесь.
Вопрос: нафига нам вообще объект passObj, если проверка пароля происходит сразу же после? Чем обычный if не угодил?

Паролить объекты на клиенте - глупость, посмотреть их содержимое труда не составит.

Если хотите поиграться, то используйте для своей задачи Proxy.

Пароль у вас запрашивается только единожды потому, что у вас так код написан.

Строка 19 - вызов геттера из строк 12..15;
Если пароль верный, то в переменную obj записывается объект, на который до перезаписи значения ссылается переменная obj. Если пароль кривой, то в переменную obj записывается undefined, т.к. alert ничего не возвращает.

В итоге вы либо каждый раз (строки 21..23) просто обращаетесь напрямую к изначальному объекту, либо к undefined.
Ответить с цитированием
  #3 (permalink)  
Старый 13.07.2020, 20:18
Интересующийся
Отправить личное сообщение для Launder Посмотреть профиль Найти все сообщения от Launder
 
Регистрация: 25.04.2019
Сообщений: 19

Ошибка ясна, геттер выдаёт значение, а значение - объект. Вызвав один раз, мы сохранили прямую ссылку на объект в переменную, вот пароль и не нужен. Грубо говоря, при вызове
alert( passObj.p.a );
а далее, в конце вместо a поставлять b и c, то пароль потребуется каждый раз. Также можно сделать функцию
let getObj = function acc() {  return passObj.p  }
и вызывать вот так:
alert( getObj().a );

Но, поместить геттер в переменную, похоже, увы, не получится - только её результат. А результат уже обнаружит себя, то есть поместить функцию (которая запрашивает пароль), под видом "просто объекта", уже врят ли получится...
Паролить на клиенте я не собираюсь, просто это наглядный(для меня) пример оболочки на объект. Как раз и хочу понять, насколько прозрачную можно сделать оболочку на объект и есть ли, при этом, альтернатива и прокси.
Ответить с цитированием
  #4 (permalink)  
Старый 13.07.2020, 21:02
Профессор
Отправить личное сообщение для Nexus Посмотреть профиль Найти все сообщения от Nexus
 
Регистрация: 04.12.2012
Сообщений: 3,703

function protectObject(object, password) {
    if (!password) {
        return object;
    }

    return new Proxy(object, {
        get(target, name) {
            const pwd = prompt('Enter password');
            if (!pwd || pwd !== password) {
                throw new Error('Access denied');
            }

            return target[name];
        }
    });
};

var a = {a: 1, b: 2, c: 3},
    p = protectObject(a, 'asd');

try {
    alert(p.a);
} catch (e) {
    alert(e.message);
}
Ответить с цитированием
  #5 (permalink)  
Старый 13.07.2020, 21:30
Интересующийся
Отправить личное сообщение для Launder Посмотреть профиль Найти все сообщения от Launder
 
Регистрация: 25.04.2019
Сообщений: 19

Я пробовал подобное.
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Ext.Component.draggable - Область ограничения произвольной формы khusamov ExtJS 4 15.07.2015 00:46
Нужна помощь по снятию ограничения прога"Размеры" SerfUA jQuery 3 29.07.2014 16:57
UserJs, ограничения... Nexus Общие вопросы Javascript 2 14.07.2013 10:30
Ограничения ввода цифр от (2 символов до 10) Sakyra Общие вопросы Javascript 1 13.05.2013 14:19
Setter / getter mexoboy Общие вопросы Javascript 4 28.03.2010 15:53