Динамическая настройка методов получения и настройки для класса

#javascript

#javascript

Вопрос:

Я могу установить свойство класса извне из строкового значения после его создания следующим образом

 class Class {
  //Nothing
}

let storageClass = new Class();

storageClass['value'] = 'Hello World';

document.write(storageClass.value); 

Но мне нужно отслеживать изменения всех атрибутов, чтобы я мог использовать get и set , но тогда я не могу добавить новое свойство, основанное только на storageClass['value'] = 'Hello World'; . Например, мне пришлось бы добавить функции get и set, если бы я хотел сделать storageClass['valueNumberTwo'] = 'A Second Value';

 class Class {
  get value() {
    return this._value;
  }
  
  set value(value) {
    this._value = value;
    console.log('Value Changed');
  }
}

let storageClass = new Class();

storageClass['value'] = 'Hello World';

document.write(storageClass.value); 

Есть ли способ сделать это, если я знаю все свойства, которые могут быть созданы при создании класса?

Комментарии:

1. Почему вы говорите, что не можете использовать storageClass['value'] = 'Hello World'; , если используете геттеры и сеттеры?

2. Разве мне не нужно создавать set myCustomValue() и get myCustomValue() для каждого из них?

3. Да, вам нужно будет.

4. Есть ли способ создать set и get для всех свойств?

5. Проверьте мой отредактированный ответ. Моя цель — иметь возможность использовать что-то вроде storageClass['valueNumberTwo'] = 'A Second Value'; добавления дополнительных функций set и get

Ответ №1:

Вы можете использовать a Proxy для обработки динамических операций получения и установки.

 class Class {
  constructor() {
    return new Proxy(this, {
      get(target, prop, receiver) {
        return target['_'   prop];
      },
      set(obj, prop, value) {
        obj['_'   prop] = value;
        console.log('value changed');
      }
    });
  }
}
let storageClass = new Class;
storageClass['value'] = 'Hello World';
document.write(storageClass.value); 

Комментарии:

1. Спасибо, в любом случае я мог бы сделать это внутри класса, а не когда я его объявляю?

2. @Jack Вы можете вернуть Proxy из конструктора.

Ответ №2:

Вы можете создать a get/set для всех свойств, используя конструкцию ES6 Proxy , которая позволяет вам реализовывать низкоуровневые методы для объекта (например get , который вызывается при обращении к любому свойству).

Подробности см. в документации Mozilla.

Обратите внимание, что в качестве функции ES6 это имеет широкую, но не универсальную поддержку браузера (например, не работает в Internet Explorer) и не может быть заполнено, поскольку используемые функции не существовали в более старых версиях JavaScript.