【发布时间】:2020-02-15 20:20:53
【问题描述】:
问题:我正在重新编写一个返回一个大的纯 javascript 对象的函数。调用者不应修改原始对象。该函数当前被数百个调用者调用。
一些解决方案:
- 返回对象的深层副本。这是当前的解决方案。这很糟糕,因为 (a) 对象非常大,并且 (b) 90% 的情况下不需要克隆,因为大多数调用者不会修改值。
- 返回对对象的引用。这很糟糕,因为调用者将能够修改我不想要的原始对象。
- 返回带有
Object.freeze或类似名称的引用。如果我可以保证调用者不会尝试修改返回值,这可能会起作用。但我不能切实地保证这一点。同样,该函数被数百个调用者调用,并且许多调用者已经修改了(克隆的)值。
我想要的是一种具有以下两个属性的写时复制解决方案:
- 函数的返回值是对原始对象的引用,直到值被修改。
- 值修改后,成为原对象的深度克隆。
我做了一些测试,我可以使用 Javascript Proxy 来实现它。只需捕获所有修改目标的操作(即set、deleteProperty、defineProperty 等)以侦听更改。然后捕获get 以在未进行任何更改时返回引用,如果已进行更改则返回克隆。代理还必须是深度代理才能侦听嵌套属性的更改。
虽然我可以自己实现它,但我想知道是否已经有任何实现。如果没有必要,我宁愿不重新发明轮子。浏览器兼容性很好,但不是必需的。
【问题讨论】:
-
看起来
cow是你需要的 npmjs.com/package/cow -
@artanik 嗯……这看起来很有希望。谢谢!
-
你试过 immer 包吗
标签: javascript proxy