Проблема: я переписываю функцию, которая возвращает большой простой javascript объект. Исходный объект не должен быть изменен вызывающими. В настоящее время функция вызывается сотнями вызывающих абонентов.
Некоторые решения:
- Возвращает глубокую копию объекта. Это текущее решение. Это плохо, потому что (а) объект очень большой, и (б) 90% времени клон не нужен, потому что большинство вызывающих не изменяют значение.
- Возвращает ссылку на объект. Это плохо, потому что вызывающие абоненты смогут изменять исходный объект, который я не хочу.
- Возвращать ссылку с
Object.freeze
или что-то подобное. Это могло бы сработать, если бы я мог гарантировать, что вызывающие не будут пытаться изменить возвращаемое значение. Но я не могу реально гарантировать это. Опять же, функция вызывается сотнями вызывающих абонентов, и многие уже изменяют значение (клон).
Мне нужно решение с копированием при записи, которое имеет следующие два свойства:
- Возвращаемым значением функции является ссылка на исходный объект до тех пор, пока значение не будет изменено.
- После изменения значения оно становится глубокий клон исходного объекта.
Я провел несколько тестов и могу реализовать это с помощью Javascript Proxy . Просто ловите все операции, которые изменяют цель (например, set
, deleteProperty
, defineProperty
, et c.), Чтобы прослушать изменения. Затем перехватите get
, чтобы вернуть ссылку, если не было внесено никаких изменений, и вернуть клон, если изменения были сделаны. Прокси-сервер также должен быть глубоким прокси-сервером для прослушивания изменений во вложенных свойствах.
Хотя я могу реализовать это сам, мне было интересно, существуют ли уже какие-либо реализации. Я бы предпочел не изобретать велосипед, если мне не нужно. Совместимость браузера приятна, но не обязательна.