Чи є в JavaScript можливість створити "слабку посилання" на інший об'єкт? Ось сторінка вікі з описом того, що таке слабке посилання. Ось ще одна стаття, яка описує їх на Java. Чи може хтось придумати спосіб реалізувати цю поведінку в JavaScript?
Чи є в JavaScript можливість створити "слабку посилання" на інший об'єкт? Ось сторінка вікі з описом того, що таке слабке посилання. Ось ще одна стаття, яка описує їх на Java. Чи може хтось придумати спосіб реалізувати цю поведінку в JavaScript?
Відповіді:
Немає мовної підтримки для слабких файлів у JavaScript. Ви можете прокрутити свій власний, використовуючи ручний підрахунок посилань, але не особливо плавно. Ви не можете створити об’єкт обгортки проксі, тому що в JavaScript об’єкти ніколи не знають, коли вони збираються збирати сміття.
Таким чином, ваша "слабка посилання" стає ключем (наприклад, цілим числом) у простому пошуку, з методом додавання довідки та видалення-посилання, а коли вже немає посилань, відслідковуваних вручну, запис можна видалити, залишаючи майбутні огляди на цей ключ для повернення нуля.
Це насправді не слабке місце, але воно може вирішити деякі ті самі проблеми. Зазвичай це робиться в складних веб-додатках для запобігання витоку пам’яті з браузерів (як правило, IE, особливо старіших версій), коли між вузлом DOM або обробником подій є об'єктом посилання та об'єктом, пов’язаним з ним, таким як закриття. У цих випадках повна схема підрахунку довідок може навіть не знадобитися.
Під час запуску JS на NodeJS ви можете врахувати https://github.com/TooTallNate/node-weak .
Поки що неможливо використовувати слабкі посилання, але, швидше за все, незабаром це стане можливим, оскільки WeakRefs в JavaScript - це робота в процесі роботи. Деталі нижче.
Пропозиція, що знаходиться зараз на етапі 3, означає, що вона має повну специфікацію і що для подальшого вдосконалення потребуватиме зворотного зв’язку від реалізацій та користувачів.
Пропозиція WeakRef включає два основні нові функції:
Первинне використання слабких посилань є реалізація кешей або відображень , що займають великі об'єкти, де це бажано, щоб великий об'єкт не залишав в живих тільки тому , що з'являється в кеші або відображення.
Фіналізація - це виконання коду для очищення після об'єкта, який став недоступним для виконання програми. Зазначені користувачем фіналізатори дозволяють отримати кілька нових випадків використання та можуть запобігти витоку пам’яті під час керування ресурсами, про які збирач сміття не знає.
https://github.com/tc39/proposed-weakrefs
https://v8.dev/features/weak-references
Справжні слабкі посилання, ні, ще немає (але виробники браузерів дивляться на тему). Але ось ідея про те, як імітувати слабкі посилання.
Ви можете створити кеш, через який ви керуєте своїми об'єктами. Коли об’єкт зберігається, кеш зберігає передбачення, скільки пам'яті займе об'єкт. Для деяких предметів, як-от зберігання зображень, це прямо вперед. Для інших це було б складніше.
Коли вам потрібен об'єкт, ви запитуєте його кеш. Якщо в кеші є об'єкт, він повертається. Якщо його немає, то елемент генерується, зберігається та повертається.
Слабі посилання моделюються елементами видалення кеша, коли загальна кількість передбачуваної пам'яті досягне певного рівня. Він спрогнозує, які предмети найменше використовуються, виходячи з того, як часто їх витягують, зваживши на те, як давно їх вивезли. Вартість "розрахунку" також може бути додана, якщо код, який створює елемент, передається в кеш як закриття. Це дозволить кешу зберігати елементи, які дуже дорого створювати або генерувати.
Алгоритм видалення є ключовим, тому що якщо ви помилитесь, тоді ви зможете видалити найпопулярніші елементи. Це призвело б до страшної роботи.
Поки кеш є єдиним об'єктом, який має постійні посилання на об'єкти, що зберігаються, тоді вищевказана система повинна працювати досить добре, як альтернатива справжнім слабким посиланням.
Просто для довідки; У JavaScript його немає, але ActionScript 3 (який також є ECMAScript). Перевірте параметр конструктора для словника .
Використання механізму кешування емулювати слабкі посилання, так як JL235 запропоновано вище , є розумним. Якщо слабкі посилання існуватимуть на самому собі, ви б спостерігали таку поведінку:
this.val = {};
this.ref = new WeakReference(this.val);
...
this.ref.get(); // always returns val
...
this.val = null; // no more references
...
this.ref.get(); // may still return val, depending on already gc'd or not
Тоді як із кешем ви б спостерігали:
this.val = {};
this.key = cache.put(this.val);
...
cache.get(this.key); // returns val, until evicted by other cache puts
...
this.val = null; // no more references
...
cache.get(this.key); // returns val, until evicted by other cache puts
Як власник посилання, ви не повинні робити жодних припущень щодо того, коли воно посилається на значення, це не відрізняється за допомогою кешу
Нарешті вони тут. Ще не реалізовано в браузерах, але незабаром буде.
EcmaScript 6 (ES Harmony) має об'єкт WeakMap . Підтримка веб-переглядачів серед сучасних браузерів досить хороша (останні 3 версії Firefox, хром і навіть майбутня версія IE підтримують це).
WeakMap
Не дають слабкі посилання на objects-- це не цінності , які є слабкими посиланнями в WeakMap, але ключі . Той факт, що на карті існують слабкі посилання, є лише механізмом запобігання витоку пам’яті, а користувач не може спостерігати інакше.
weakmap.get(new String('any possible key that has ever existed or ever will exist'))
це завжди буде undefined
. Не корисно. Вниз голосування!
http://www.jibbering.com/faq/faq_notes/closures.html
ECMAScript використовує автоматичний збір сміття. У специфікації не визначені деталі, що залишає це для розробників, щоб розібратися, а деякі реалізації, як відомо, надають дуже низький пріоритет своїм операціям з вивезення сміття. Але загальна ідея полягає в тому, що якщо об’єкт стає нерециркульованим (не маючи інших посилань на нього, залишається доступним для виконання коду), він стає доступним для збору сміття і в якийсь майбутній момент буде знищений, а будь-які ресурси, які він споживає, звільняються і повертаються до системи для повторного використання.
Зазвичай це стосується виходу із контексту виконання. Структура ланцюга діапазону, об'єкт активації / змінної та будь-які об'єкти, створені в контексті виконання, включаючи функціональні об'єкти, більше не будуть доступні і тому стануть доступними для збору сміття.
Тобто слабких немає лише тих, які більше не стають доступними.