Удаленный ключ в WeakMap

Изучав тему Weakmap, наткнулся на строку:

"Теперь john существует только как ключ в WeakMap и может быть удалён оттуда автоматически."

Но у меня ключ в виде johh не существует в WeakMap, он удалился оттуда.

alert выдает false при попытке вызвать ключ john , но почему, если ключ john
должен сохраниться согласно этому учебнику: https://learn.javascript.ru/weakmap-weakset

let john = {};

let weakmap = new WeakMap();
weakmap.set(john,'');

john = null;

alert(weakmap.has(john));  // Выдает false, значит ключ john не сохранился


Ответы (2 шт):

Автор решения: Bear Vorkuta
let john = {};
let weakmap = new WeakMap();

здесь вы передаете не сам объект, а ссылку на него

  weakmap.set(john,'');

Ниже аналогичная ситуация

console.log(weakmap.has(john)); //выведет true, потому как передали верную ссылку

john = null;

console.log(weakmap.has(john)); //выведет false, так как ссылка нулевая, weakmap не нашел объект по этой ссылке

если в консоли после этого вывести weakmap, то увидите, что ключ в виде объекта на месте

P.S. хотя судя по логике "WeakMap" - объект должен удалиться из памяти. И как ключ в weakmap тоже )))

→ Ссылка
Автор решения: Alexander Lonberg

Пример, в вопросе, не отражает возможности использования WeakMap.

WeakMap применим для сопоставления объектов и данных в изолированном от "Внешнего_Мира" коде, или же, когда мы сами желаем самоизолироваться.

class User { constructor(name) { this.name = name } }
let john = new User('john')
let maikl = new User('maikl')
let weakmap = new WeakMap()
// Мы можем ничего не знать об экземплярах User, но сопоставить с ними необходимые данные
weakmap.set(john, 'john')
weakmap.set(maikl, 'maikl')
// Удалим ссылку на одно из значений
john = null

Видим, что WeakMap автоматически удалил 'john' и оставил только 'maikl'.

введите сюда описание изображения

Пример из 3085 года.

В районе Альфа-Центавра идут ожесточенные бои с инопланетянами. Каждый воин засекречен - мы можем его видеть(когда он рядом), но ничего не знать о его судьбе(это важно).

class Warrior {
  secretAccess(key) {...}
}
// Так воины и отправляются в полет
Spaceship.toSend(Object.seal(new Warrior(...)), ...)

Рядом находится межгалактическая столовая.
В столовой на раздаче работает Maikl, которого строго настрого предупредили:

  • Каждому воину можно выдавать 90 пайков в месяц, не более. Не волнуйся, в день около 50-100 посещений, запомнишь.

Maikl недолго думая, заводит себе блокнот, где сопоставляет воина и кол-во выданных пайков с начала дня/месяца его регистрации:

class Notepad extends Map {

  // Так Maikl получает необходимое кол-во пайков и обновляет данные
  getCount(warrior, requirement) {
    return this.has(warrior)
      // Если есть запись, проверяем сколько было выдано пайков воину
      ? this._inspect(warrior, requirement)
      // ... иначе добавим запись в блокнот
      : this._addWarrior(warrior, requirement)
  }

  _inspect(warrior, requirement) {
    let data = this.get(warrior)
    let currentDate = new Date()
    // Если достигли разницы в один месяц можно сбросить данные
    if ((new Date(currentDate - data.date)).getMonth()) {
      return this._addWarrior(warrior, requirement)
    }
    // Иначе считаем возможное кол-во выдачи
    if (data.count + requirement > 90) {
      requirement = 90 - data.count
      data.count = 90
    } else {
      data.count += requirement
    }
    return requirement
  }

  _addWarrior(warrior, requirement) {
    let data = {
      date: new Date(),
      count: requirement > 90 ? (requirement = 90) : requirement
    }
    this.set(warrior, data)
    return requirement
  }

}

По началу, все было неплохо. Но к концу месяца, Maikl изрядно устал - приходится проверять уже тысячи записей и так с каждым воином. Maikl идет к Капитану:

  • Капитан, так больше нельзя, воины "гибнут", а у меня нет доступа к информации об их судьбе что'б удалить запись. Почему я должен хранить и перелопачивать тысячи записей блокнота, когда в живых около сотни? Да и память в моем компе переполняется.

Капитан лезет на SO за советом через межгалактический ВиПиЭн и дарит Maikl-у новый блокнот:

class WeakNotepad extends WeakMap {/* то же что и выше */}

С удивлением для себя, Maikl обнаруживает - в его блокноте присутствуют только актуальные записи. Темная_Материя(Сборщик_Мусора) автоматически "чистит_WeakNotepad" и предотвращает утечку памяти. Да и времени на проверку записей уходит в несколько раз меньше. Кроме того, Maikl-у не пришлось налаживать внешние связи, запрашивать секретные "слитые_данные" о "погибших" и заниматься невверенными ему делами.

→ Ссылка