Можно ли создать "слабую ссылку" в javascript?

Есть ли способ в javascript создать «слабую ссылку» на другой объект? Вот вики-страница, описывающая, что такое слабая ссылка.Вот еще одна статья, описывающая их на Java. Может кто-нибудь придумать способ реализовать это поведение в javascript?

Обсуждаются слабые ссылки для ES6. Не спускайте глаз с глаз.

Ryan Smith 02.03.2013 19:59

* Официальная вики-страница спецификаций / обсуждение на wiki.ecmascript.org/doku.php?id=strawman:weak_refs, в настоящее время «Последнее изменение: 02.02.2013 22:25» * некоторые другие обсуждения спецификации на esdiscuss.org/topic/what-is-the-status-of-weak-references, в настоящее время последнее сообщение «Вс, 3 марта, 11:56:05 PST 2013»

Destiny Architect 25.10.2014 08:21

В большинстве случаев WR - это попытка решить Проблема с задержанным слушателем, обсуждаемую здесь: [stackoverflow.com/questions/43758217/…. Если бы на этот вопрос был хороший ответ, я не думаю, что в WR было бы много нужды.

James 27.04.2018 14:11

@supercat Я отправил ответ на недействительный вопрос слушателя.

James 18.08.2018 21:23
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
101
4
29 496
10
Перейти к ответу Данный вопрос помечен как решенный

Ответы 10

http://www.jibbering.com/faq/faq_notes/closures.html

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

Обычно это происходит при выходе из контекста выполнения. Структура цепочки областей видимости, объект Activation / Variable и любые объекты, созданные в контексте выполнения, включая объекты функций, больше не будут доступны и, следовательно, станут доступными для сборки мусора.

То есть слабых нет, есть только те, которые больше не доступны.

Избегание циклов ссылок - не единственная причина использовать слабые ссылки. Они очень удобны для объединения / кеширования экземпляров объектов и т. д.

fluffy 04.06.2011 10:53

Определение WeakReference не является вопросом. Также согласен с комментарием выше.

Yuri Yaryshev 22.05.2018 10:05
Ответ принят как подходящий

Обновление: с июля 2020 года в некоторых реализациях (Chrome, Edge, Firefox и Node.js) была поддержка WeakRef, как определено в Предложение WeakRefs, который по состоянию на 16 декабря 2020 года является «черновиком этапа 3».

В JavaScript нет языковой поддержки для weakrefs. Вы можете свернуть свой собственный, используя ручной подсчет ссылок, но не особенно плавно. Вы не можете создать объект-оболочку прокси, потому что в JavaScript объекты никогда не знают, когда они собираются собирать мусор.

Таким образом, ваша `` слабая ссылка '' становится ключом (например, целым числом) при простом поиске с помощью методов добавления ссылки и удаления ссылки, а когда больше нет отслеживаемых вручную ссылок, запись может быть удалена, оставив будущие поиски этот ключ для возврата null.

На самом деле это не слабая ссылка, но она может решить некоторые из тех же проблем. Обычно это делается в сложных веб-приложениях, чтобы предотвратить утечку памяти из браузеров (обычно IE, особенно более старые версии), когда существует цикл ссылок между узлом DOM или обработчиком событий и связанным с ним объектом, например закрытием. В этих случаях полная схема подсчета ссылок может даже не потребоваться.

Я внимательно не изучал (и не использовал) код, но у es-lab есть сценарий, обеспечивающий базовый Эмуляция WeakMap. Аврора 6 (Mozilla) имеет нестандартный Реализация WeakMap.

theazureshadow 17.06.2011 12:04

С ES6 этот ответ больше неверен. Смотрите мой ответ ниже stackoverflow.com/a/28567560/745190

thelastshadow 16.03.2015 16:02

Это все еще верно, потому что ES6 WeakMaps не являются истинными слабыми ссылками. WeakMaps принимает объекты только как ключи, и ссылки на эти объекты хранятся слабо. См. stackoverflow.com/questions/32397729/…

CodeManX 04.09.2015 16:24

Я написал класс для имитации слабой карты и разместил его здесь: stackoverflow.com/a/47017206/491553

Ryan Shillington 30.10.2017 17:05

Просто для справки; В JavaScript этого нет, но в ActionScript 3 (который также является ECMAScript) есть. Проверьте параметр конструктора для словаря.

Истинных слабых ссылок нет, пока нет (но производители браузеров смотрят на эту тему). Но вот идея, как имитировать слабые ссылки.

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

Когда вам нужен объект, вы затем запрашиваете его у кеша. Если в кеше есть объект, он возвращается. Если его там нет, то элемент создается, сохраняется, а затем возвращается.

Слабые ссылки моделируются путем удаления элементов кэша, когда общий объем прогнозируемой памяти достигает определенного уровня. Он предскажет, какие элементы используются меньше всего, в зависимости от того, как часто они извлекаются, с учетом того, как давно они были извлечены. «Расчетная» стоимость также может быть добавлена, если код, создающий элемент, передается в кеш в качестве закрытия. Это позволит кешу хранить элементы, создание или создание которых очень дорогое.

Алгоритм удаления является ключевым, потому что, если вы ошибетесь, вы можете удалить самые популярные элементы. Это привело бы к ужасной производительности.

Пока кеш является единственным объектом со ссылками постоянный на сохраненные объекты, указанная выше система должна работать довольно хорошо как альтернатива истинным слабым ссылкам.

Разве большая часть того, что вы сказали, не имеет отношения к weakrefs?

Erik Kaplun 19.12.2011 23:04

@ErikAllik Чаще всего слабые ссылки используются для хранения больших объемов данных и их удаления, если у вас заканчивается место. Я описал способ подделать это, автоматически отслеживая память самостоятельно и удаляя элементы, когда они больше не нужны.

JL235 03.02.2012 13:23

@ JL235 - слабые ссылки важны не для кешей, а для обработчиков событий. У меня есть объект, который, пока существует, должен наблюдать какое-то другое событие, но я не хочу, чтобы тот факт, что он находится в списке уведомлений, составлял ссылку для целей GC.

Malvolio 01.05.2012 23:10

@Malvolio: Я успешно использовал слабые ссылки для кешей в Java, и они хорошо работают.

JL235 06.07.2012 04:03

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

fabspro 31.05.2013 12:29

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

Phil Freeman 08.08.2013 22:00

+1. Использование слабых ссылок с кешированием имеет смысл при описанном здесь способе. К сожалению, это невозможно с JS, поэтому описанный вами подход кажется лучшей альтернативой и, возможно, даже лучше, чем использование слабых ссылок, поскольку он дает больше контроля за счет более явной реализации.

Drew Noakes 15.10.2013 14:14

Кеширование традиционно является основной причиной слабых ссылок. Обработчик событий DOM - это всего лишь некоторая ошибка IE Explorer.

axkibe 18.12.2013 13:28

При запуске JS на NodeJS вы можете рассмотреть https://github.com/TooTallNate/node-weak.

EcmaScript 6 (ES Harmony) имеет объект WeakMap. Поддержка браузеров среди современных браузеров - довольно хорошо (последние 3 версии Firefox, Chrome и даже будущая версия IE поддерживают его).

Это не совсем то же самое. WeakMap не дает слабых ссылок на объекты - это не значения, которые являются слабыми ссылками в WeakMap, а ключи. Тот факт, что на карте существуют слабые ссылки, - это только механизм предотвращения утечки памяти, и в противном случае пользователь не может наблюдать их.

EyasSH 09.05.2015 00:07

Вы правы, что слабые ключи, а не значения. Но вся цель использования слабых ссылок - разрешить сборку мусора для указанного объекта. OP опубликовал две ссылки, вторая из которых касается добавления идентификатора к объекту, который вы не можете расширить, и на самом деле он рекомендует использовать WeakHashMap, Java-эквивалент WeakMap в JavaScript.

thelastshadow 11.05.2015 12:04

удачи в использовании WeakMap для реализации слабой ссылки, поскольку weakmap.get(new String('any possible key that has ever existed or ever will exist')) будет всегда быть undefined. Нет полезно. Голосование против!

user3338098 12.05.2016 02:58

Использование механизма кэширования для имитации слабой ссылки, как 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

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

Наконец-то они здесь. Еще не реализовано в браузерах, но скоро будет.

https://v8.dev/features/weak-references

Обновление: сентябрь 2019 г.

Пока что нельзя использовать слабые ссылки, но, скорее всего, скоро это станет возможно, так как Слабые ссылки в JavaScript находятся в стадии разработки. Подробности ниже.

Предложение

Предложение сейчас в 3 этап, что означает, что он имеет полный Спецификация и что дальнейшее уточнение потребует обратной связи от реализаций и пользователей.

Предложение WeakRef включает в себя две основные новые функциональные возможности:

  • Создание слабых ссылок на объекты с помощью WeakRef класс
  • Запуск определяемых пользователем финализаторов после того, как объекты собраны мусором, с FinalizationGroup класс

Случаи применения

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

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

Источник и дальнейшее чтение

https://github.com/tc39/proposal-weakrefs
https://v8.dev/features/weak-references

Firefox Nightly добавил экспериментальную поддержку WeakRef. Вот пример реализации, использующей его для создания итеративной версии WeakSet: gist.github.com/seanlinsley/bc10378fd311d75cf6b5e80394be813d

seanlinsley 22.03.2020 00:03

2021 Обновление

WeakRef теперь реализован в Chrome, Edge и Firefox. Все еще ждем Safari и некоторых других противников.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakRef

Другие вопросы по теме