Как стать автором
Обновить

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

Ещё одна причина посмотреть в сторону typescript. Там это из коробки.

enum Color {
  Red,
  Green,
  Blue
}
class Colors {
  [key: string]: Color;
}

const colors = new Colors();
colors['red'] = Color.Red;

Доступ на чтение/запись через квадратные скобки испокон веку есть и в JS. Статья о том, как этот доступ обвесить кастомной логикой.

К сожалению нет. Методы getColor и setColor, выполняющие роль геттера и сеттера могут иметь сложную логику. В вашем примере, такого нет.

Возможно я сделал недостаточно выразительные примеры в статье.

В свою очередь, мне было бы интересно узнать, есть ли еще способы реализовать [] нотацию без использования Proxy.

const foo = {}

foo["color"] = "red";

foo["color"] // > "red"
"color" in foo // > true 

Это я к тому что это просто стандартное поведение js. Даже прокси не нужны.

Сложности появляются если вам при этом нужно сделать дополнительные действия при этом, например, перерисовать все зависимые элементы (mobx, короче). Тут задача разбивается на две категории: список всех известных полей заранее известен и не известен. В первом случае можно через defineProperty выкрутиться, ещё вроде был метод watch, но либо был очень давно либо мне приснился.

Во втором случае, когда список свойств, в которые будут записывать или считывать, не известен, уже без прокси не обойтись (либо нужно менять структуру на такую, при которой он известен или пользоваться getItem/setItem).

Я налажал с примером пытясь его упростить. Да, речь про сложную логику в геттере/сеттере.

Есть, к слову, странный способ обойтись без прокси, но требует, мягко говоря, значительных телодвижений, вплоть до целой архитектуры, заточенной под эти изменения. В целом я говорю про первый ангулар, он же нынче angularjs, в котором есть специфичный digest цикл. Суть в том, что все изменения над объектом должны проводиться только внутри специальной функции (в случае с ангуларом все хендлеры и методы были автоматически обёрнуты в этот цикл), которая после завершения всех операций, сравнивает предыдущее состояние объекта и новое и, таким образом, определяет какие поля поменялись. Если вы поменяете поле два раза и более внутри одного цикла, обработчик сработает только раз, и вообще не сработает если вы поменяете его обратно на значение с которого начинали.

Звучит как безумие, но тот же redux не то чтобы далеко ушёл от этой идеи.

Во втором+ ангуларе используются «зоны» (zone.js) для этого, но не уверен как они работают, так что ничего утверждать не буду.

Можно динамически добавлять и удалять геттеры и сеттеры на объект через Object.defineProperty, однако полноценной перегрузки операторов в JavaScript пока нету.

Такие вот геттеры-сеттеры уровня объекта — это, конечно, хорошо и удобно. Но позволяют писать такой монструозный код, что обфускаторы утратят актуальность

НЛО прилетело и опубликовало эту надпись здесь

Спасибо. Этот метод мне действительно кажется удобней, чем я описал в статье.

Спасибо, очень крутой пример.

НЛО прилетело и опубликовало эту надпись здесь

Базовый аспект языка, действительно повод для написания статьи?

Вы внимательно прочитали содержание?

Не очень понял, для чего это делать? Реализовывать сложную логику в гетерах/сетерах? Они не предназначены для этого. Когда я вызываю color.get("#colorName"), я не ожидаю, что произойдет запуск ракеты. Когда я пытаюсь прочитать color["#colorName"], то вообще не ожидаю исполнения какой-либо логики. Зачем?

Речь не про запуск ракеты, а про любые действия производимые при вызове свойства. Например, при установке цвета чего-то (colors['toolbar'] = 'red') у вас этот элемент должен автоматически применить цвет.

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации