Properties of Cloned Objects in Locker vs LWS

If you clone objects using JSON.stringify(o), the behavior in LWS is different compared to Lightning Locker. Your code might rely on a non-standard behavior of Lightning Locker that doesn't occur with LWS.

In Lightning Locker, platform objects are replaced with a secure wrapper. To illustrate the behavior, let’s look at the Event object. Event objects are exposed as SecureEvent objects. SecureEvent objects are new objects in which all the inherited and direct properties of the original Event object become direct properties in the new object. Direct properties are called "own properties". The conversion to own properties means that the inherited property Event.prototype.detail becomes an own property of the SecureEvent instance.

JSON.stringify(o) only operates on own properties, but if you use it on an Event object when Lightning Locker is enabled, all the properties are included because SecureEvent converts them to own properties. Under Lightning Locker, you can “clone” received objects by using JSON.parse(JSON.stringify(o)).

LWS doesn’t use secure wrappers, and objects typically behave as they would on the browser platform. For the Event object under LWS, Event.prototype.detail isn’t included in the properties serialized by JSON.stringify(o), because that property is inherited and is not an own property. Therefore, techniques that rely on all properties being serialized won’t work the same in LWS.

CustomEvent object cloning through JSON.parse(JSON.stringify(o)) is one area where developers have run into issues while transitioning to LWS. CustomEvent.detail is not an own property so it’s stripped away when cloning.

For example, this code works in Lightning Locker only because wrapping by SecureEvent converts the detail property to an own property that JSON.parse(JSON.stringify(event)) can parse.

To pass the value of the detail property of an Event object, we recommend destructuring the property from the object and reassigning into a new object.