You can just do:

const proxy = new Proxy(obj, {
   set() { throw new Error(); },
   defineProperty() { throw new Error();},
   deleteProperty() { throw new Error(); }
})
this.emit('some:event', proxy)


Though, it seems like an exotic use case.

On Mon, Feb 19, 2018 at 8:56 PM, /#!/JoePea <j...@trusktr.io> wrote:

> ​
> I think the ability to unfreeze an object can be useful.
>
> For example, suppose we have a library that emits events:
>
> ```js
> this.emit('some:event', this.obj)
> ```
>
> Maybe we want to try to prevent external listeners from modifying the
> event payload without having to clone `this.obj`, otherwise cloning can
> cause "jank" from GC during animations that should be smooth.
>
> So, what if there was a way to unfreeze an object in the scope in which
> the object was frozen?
>
> ```js
> Object.freeze(obj) // instead of cloning
> this.emit('some:event', this.obj) // recommend all listeners to be
> synchronous, and not modify the payload later
> Object.unfreeze(this.obj) // in the same scope
> ```
>
> or maybe it return an unfreeze function:
>
> ```js
> const unfreeze = Object.freeze(obj) // instead of cloning
> this.emit('some:event', this.obj) // recommend all listeners to be
> synchronous, and not modify the payload later
> unfreeze(this.obj) // only code that is given the unfreeze function can
> call it, similar to resolve/reject functions with Promises
> ```
>
> or maybe it is more similar to setTimeout and setInterval:
>
> ```js
> const frozenKey = Object.freeze(obj) // instead of cloning
> this.emit('some:event', this.obj) // recommend all listeners to be
> synchronous, and not modify the payload later
> Object.unfreeze(frozenKey) // only code that is given the key can unfreeze
> the object associated with the key
> ```
>
> It seems like there can be opportunity for this to be optimized, so that
> it can be faster than cloning. For example, this uses more memory and
> causes GC:
>
> ```js
> this.emit('some:event', { ...this.obj }) // creates a new object
> ```
>
> Could the performance benefit make it worth it to have a way to unfreeze
> objects?
>
> Another use case is unlocking things only when used in certain places, as
> a "guard". In the following example, the only way to set the X rotation
> value is with the setter, which enforces that certain logic will fire,
> rather than someone from the outside modifying the readable state not using
> the setter:
>
> ```js
>
> import Privates from 'somewhere'
>
> // a private cache, using WeakMap internally
> const _ = new Privates
>
> class ThingThatRotates {
>     constructor() {
>         this.rotation = { x: 0, y: 0, z: 0 }
>         _(this).frozen = Object.freeze(this.rotation)
>         // ...
>     }
>
>     get rotateX() { return this.rotation.x }
>     set rotateX(val) {
>         this.doSomethingImportantWithTheValue(val)
>
>         // unlock here, so that the value can only be set with this setter.
>         Object.unfreeze(_(this).frozen)
>         this.rotation.x = val
>         _(this).frozen = Object.freeze(this.rotation)
>
>         this.emitAnEventWithTheValue(val)
>         this.etc(val)
>     }
>
>     // ...
> }
>
> ```
>
> I know, I can probably just keep `rotation` in the private cache, but then
> it isn't readable. Maybe I want that to be readable as a convenient
> shortcut. F.e.
>
> ```js
> // outside code
> const r = new ThingThatRotates
>
> // X rotation might be animated by some other tool
>
> const {x, y, z} = r.rotation // for convenience, no cloning involved.
>
> ```
>
> This is a completely contrived example I just made up right now. I can
> probably think of more. It seems like it could be good for performance in
> cases where we don't want modification from the outside...
>
>
> /#!/JoePea
>
> _______________________________________________
> es-discuss mailing list
> es-discuss@mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
>
>
_______________________________________________
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss

Reply via email to