Меняем ли мы состояния при установке новых значений в слабых картах? - PullRequest
0 голосов
/ 21 февраля 2020

Предположим, у нас есть следующий код:

const _timeStamp = new WeakMap();
const _running = new WeakMap();

export class Stopwatch {
  constructor() {
    _timeStamp.set(this, 0);
    _running.set(this, false);
  }

  start() {
    // start stopwatch
    _running.set(this, true)
    _timeStamp.set(this, Date.now())
  }

  stop() {
    // stop stopwatch
    _running.set(this, false);
    return (Date.now() - _timeStamp.get(this))/1000
  }
}

В этом примере мы пытаемся скрыть некоторую информацию от конечного пользователя, используя слабые карты. В зависимости от того, какой метод вызывается, мы меняем значения в обеих слабых картах. Когда мы переназначаем переменные, мы меняем состояния.

let x = 0;
x = 10

РЕДАКТИРОВАТЬ:


В качестве лучшей практики мы не должны мутировать объекты или изменять состояния в JS

Однако разве мы не меняем состояния при обновлении значений в слабых картах, как, например, в случае переменных? Какова «лучшая практика» при использовании частных реквизитов, которые необходимо переписать?

Любые разъяснения приветствуются!

1 Ответ

1 голос
/ 21 февраля 2020

Чтобы ответить на ваш вопрос о WeakMaps , я думаю, что вы говорите о побочных эффектах. При использовании WeakMap вы можете представить, что при установке значения отсутствует побочный эффект пользовательского пространства, поскольку WeakMaps инвертирует обычные отношения между элементом и коллекцией. В WeakMap по причинам, связанным с сборкой мусора, элемент сохраняет скрытую ссылку на коллекцию (а не коллекцию, поддерживающую ссылку на элемент), поэтому мы можем притворяться, что побочный эффект отсутствует.

Но этот вопрос также касается конфиденциальности в JavaScript.

. Как это бывает, JavaScript всегда предоставлял выдающийся (и насколько я знаю непроницаемый) - в отличие от частных полей в таких языках, как C#). для надежной конфиденциальности: закрытие. Просто большинство разработчиков приходят из класса объектно-ориентированного фона и тратят время на изучение "JavaScript way".

Тем не менее, синтаксис для пометки полей в классах как private в настоящее время равен * 1009. * Стадия 3 процесса разработки функции и поддерживается транспиляторами.

Итак, ответ таков: существует несколько способов обеспечить конфиденциальность, в зависимости от конкретного варианта использования и стиля кода вашей команды. использует.

Команды, использующие классы, вероятно, будут использовать # синтаксис поля частного класса .

class MyClass {
   #myPrivateField = 'foo'
   bar(s) {
       return this.#myPrivateField + s
   }
}

Команды, использующие функции, будут использовать замыканий .

function createObject() {
    let myPrivateVariable = 'foo'
    return {
        bar(s) {
            return myPrivateField + s
        }
    }
}

Вы можете выбрать это и сказать, что объект-функция для bar создается для каждого экземпляра. В подавляющем большинстве случаев это не имеет значения.

Символы иногда будут использоваться, хотя они обеспечивают меньшую конфиденциальность, поскольку их можно просматривать с помощью отражения.

function createObject() {    
    let secretSymbol = Symbol('secret')
    return ({
        [secretSymbol]: 'foo',
        bar(s) {
            return this[secretSymbol] + s
        }
    })
}

WeakMaps и модули также могут быть использованы. Для получения дополнительной информации см. Ссылки ниже.

Обратите внимание, что вы также можете использовать класс с закрытием, чтобы гарантировать, что переменная остается закрытой.

См. также , и .

...