And that leaves us with the proxy API, just like the other features here it's basically a meta feature
which allows us to tweak our objects or add some extra functionality to our code that kicks in when
our people work with our code,
which is why it's called meta programming.
We configure our code to behave in a certain way when other people use it, which is this extra level of
thinking we added here.
Now the proxy API is all about creating so-called traps for certain object operations and you can
almost take the words trap here literally. With the proxy API,
you can step it up on certain operations and execute your own code,
for example if someone wants to retrieve a property, so the value for a property of an object, with the
proxy API you can set up some logic that runs in that case which allows you to either change what is
returned or do some additional task, again for this meta level where you might want to track property
access or make sure the objects your library exposes are used properly.
So again, it's an API that allows you to control how your code is used and which impact it has,
now let's see it in action. To see the proxy API in action,
I'll comment out this delete property line here and instead now start working on this course object with
the proxy API,
so let's see what the proxy API can do for us there.
When I say the proxy API, I mean that there is a special object in Javascript called proxy which you
can actually instantiate,
this creates a new proxy object if you want to call it like this. Let's store this in a constant which I'll
name pcourse for proxy course because I will apply this proxy to this course object
so that we have this special course object thereafter.
Now this proxy constructor function takes the object on which this proxy should be applied,
so here I'll pass in the course object, I will point at the course object.
Now the name proxy, you might know that from networking, you can use a proxy server to disguise your
IP address for example, to basically reach out to the web by funneling your traffic over another server
which then is actually the server talking to the web sites and so on.
Now here it's kind of similar,
you wrap an extra object around your existing object,
we wrap an extra object around the course object.
Now that alone wouldn't be that useful,
instead this proxy constructor actually needs two arguments -
the first argument is the object which you want to proxy,
so which you want to wrap, the second argument is another object which defines certain handlers for the
wrapped object, so certain behaviors or certain operations you might want to perform on the wrapped
object where you can then step in. For that, I'll create a new object here and store it in a constant named
course handler
and in this object, you got certain handler functionalities, certain traps as they are called which you
can define,
for example a get trap. Now the names you can use here are clearly defined and attached you find a link
to the MDN documentation on the proxy API where you'll find all available traps and all available
operations you can listen to and step in. Here with get, I define a handler, a function in the end here
with this method syntax, which is executed whenever someone tries to read a value from the wrapped object,
so whenever someone tries to access a property, tries to get a value from a property of the wrapped object.
The get method then takes two arguments which are passed in automatically by the proxy API, the object
on which this get access happens which is our wrapped object then and the property name on which this
happened. Now
for now I will just console log property name here and then return object [property name]
which means for the wrapped object, I access this property name which you tried to access and I return a value
which is stored in there, which means I forward this value retrieval request without blocking it, without
changing it, I just retrieve the value which someone try to get for this object and give it to that
someone.
Now this course handler object is then the second argument I pass to my proxy and with that, we got the
readily configured proxy object.
Now let's see what happens if I try to access pcourse.title. This title property does exist on
this object because the proxy object which is actually stored in pcourse wraps itself around this
wrapped object and basically assumes all of the properties and methods of this wrapped object, just funnelling
all access through the traps you defined here in the handler.
So now if we save that and we reload, I do print my title here but you also see this output here, which
is coming from line 98 where I print title.
This is coming from my handler here where I log the property name and this shows that this code indeed
is executed. Whenever I try to access a property,
this code executes and tells me which property I try to access, the titled property and if I'm interested
for which object I tried to do that and then here I actually define what, for this get trap, is returned
Here I'm just getting the user who try to get this property the actual value but we could return anything
here, like the something string.
If I do that and I try to console log the title, you see instead of logging Javascript - The Complete Type,
I log something because I override what I fetched here with the help of the proxy API.
Please note that neither course nor pcourse were changed by that proxy.
If I save that and reload, you see I return something here
but we got the titles still set to Javascript - The Complete Type, both in our original object but also
in the proxy which wraps this object as you can see. So the title was not changed,
I only have this trap which steps in whenever you try to get any value of any property and which then allows
you to do stuff.
So here I am hard overridding what we returned,
a more useful behavior could be that I for example check if object property name is a thing and if it
is, I return that or with the shortcut you learned about at the beginning of this course,
I return not found. By doing that, I make sure that accessing the title should work
but for example if I try to access a length property which does not exist,
instead of getting the default value of undefined, I now get not found.
So if I reload here, we get the title but then not found instead of undefined.
So this might be a more useful scenario where we could use the proxy API,
now all of a sudden we're not using it to block access or return some dummy value but instead we're
using it to improve the usage of our object,
again keep in mind we're talking about meta programming here.
If you're writing a library which you are exposing to other users, then these users might use your exposed
object incorrectly,
maybe a developer writing some code based on your library tries to access a property which doesn't exist
in the object your library returns.
Well by default, this would give the developer undefined, maybe for your library,
you don't want to return undefined but return some other default value, like not found or a number or
another object or whatever it is and then you can just do that.
Of course you could also take into account which property the user try to access,
if the property name was length here for example, you could return something else and just have this
default fallback for any property not named length.
So for length, we could return a number of zero and only return not found for any other property which
didn't exist, like rating for example.
And now with that, if I save that, you see I get the title, then zero for the length and then not found for
the rating.
So that's what you can do with the proxy API and the get trap. Now we don't just have the get trap though.