Удаленный ключ в 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 шт):
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 тоже )))
Пример, в вопросе, не отражает возможности использования 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-у не пришлось налаживать внешние связи, запрашивать секретные "слитые_данные" о "погибших" и заниматься невверенными ему делами.
