Why are my JavaScript objects equal to Proxy {}

1.0K    Asked by debbieJha in Salesforce , Asked on Apr 23, 2021

I am loading a JavaScript object between Lightning Components

var model = {} model.user = {} model.caller = {} model.caller.name = 'Batman'; model.other = {} // etc
And then into component attributes.
cmp.set("v.model", model); cmp.set("v.caller", model.caller);
Then I use then like this:

Then I get data back out:
model.caller = cmp.get("v.caller");

My question is:

Why do my JavaScript{} object sub-objects sometimes get set to Proxy when I inspect them in the console:

caller: Proxy [[Handler]]: e [[Target]]: Object [[IsRevoked]]: false

And other times I get the values I expect...

caller { name : "Bruce Wayne" }
Answered by Deepali singh
     Reason of JavaScript{} object sub-objects sometimes get set to Proxy when injected in the console is when a component creates an intrinsic JavaScript{} object, Locker Service returns the raw JavaScript object. When Locker Service filters the object, it returns a Proxy object. Some scenarios where Locker Service filters an object and returns a Proxy object are:

Passing an object to a component in a different namespace. Passing an object from a component on API version less than 40.0 to the method of a component on API version greater than or equal to 40.0. Calling cmp.get() to retrieve an attribute value that you set with the value of a native JavaScript object or array. The object or array isn’t filtered when it’s originally created. So it has specific rules. If you store something in an attribute, it'll pop back out as a Proxy. If you pass the object via aura:method between API versions, it'll convert to a Proxy. And if you process data from a different namespace, you get a Proxy. Sometimes things get a little bit borderline, but the point of Proxy is that it attaches a custom security handler to whatever its protecting, so that public and private attributes of whatever it is you're working with won't accidentally expose hidden data. While this is really annoying in practice, its a necessary evil for Lightning to work in a consistently secure manner. Of course, once you JSON.stringify something, you get back your shiny new JSON string, but it'll be missing any attributes that were filtered out by the Proxy to avoid leaking internal data. Similarly, when you JSON.parse, you'll end up with a native object, but the moment you try to put that data anywhere in protected memory areas (e.g. an attribute), it'll eventually end up as a Proxy when you need to use it later.

    Generally speaking, when debugging, you can open the Proxy object and examine the [[Target]] attribute. Any publicly available data attributes should appear here. Of course, there's no guarantee, so you might end up needing to process the object with Object.keys, JSON.stringify, for(key in obj), and other techniques.

I've found that Object.keys seems to be the most reliable:

    var obj = component.get("v.attr"); Object.keys(obj).forEach(key => console.log(obj[key]));

If you really want to avoid working with Proxy, you can probably just set your bundle version to 39.0. Locker Service only really protects 40.0 components and up.

Your Answer


Parent Categories