Best of Modern JavaScript — Proxy Handlers
By: John Au-Yeung
Tags: JavaScript, Software Development, Programming, Technology, Web Development

Photo by Matthew Buchanan on Unsplash

Since 2015, JavaScript has improved immensely.

It’s much more pleasant to use it now than ever.

In this article, we’ll look at how to control JavaScript object operations.

Function Proxy Handlers

We can also add handler methods to the handler we pass into the Proxy constructor or Proxy.revocable method.

apply(target, thisArgument, argumentsList) lets us change the behavior of the apply or call method.

It can also change the behavior of direct calls to a function.

target is the target object which we want to control.

thisArgument lets us pass in the value of this in the function.

argumentsList lets us pass in a list of arguments.

Invariants of Handler Methods

Handler methods have various invariants enforced on them.

They include the following.

apply(target, thisArgument, argumentsList) has no invariants enforced on them.

construct(target, argumentsList, newTarget) must return an object, and not null or a primitive value.

defineProperty(target, propKey, propDesc) must not let us add [properties to an object that isn’t extensible.

The target must have a property must have a non-configurable own property with propKey if configurable is false .

If writable and configurable are both false , then we can’t write a new property to the property.

deleteProperty(target, propKey) can’t delete non-configurable own properties of the target .

get(target, propKey, receiver) must return the property’s value if it has an own, non-writable, and non-configurable data property with name propKey .

Otherwise, it must return undefined .

getOwnPropertyDescriptor(target, propKey) must return either an object or undefined .

Non-configurable now properties of the target can’t be reported as non-existent.

If the target is non-extensile, then it must report as existing.

It can’t report a non-configurable property as configurable and can’t report a different value for a non-configurable and non-writable property.

getPrototypeOf(target) must return either an object or null .

If the target isn't extensible, then the handler must return the prototype of the target object.

has(target, propKey) mustn’t hide a non-configurable own property of target .

If the target is on-extensible than no own property of target may be hidden.

isExtensible(target) must return a boolean.

The coerced boolean value must be the same as target.isExtensible .

ownKeys(target) must return an object which is treated as array-like and converted to an array.

Each element of the result must either be a string or a symbol.

The result must have the keys of all non-configurable non-inherited properties of target .

If target isn’t extensible then the result must only the keys of its own properties.

preventExtensions(target) returns a boolean.

target.isExtensible() must return false after this is called.

set(target, propKey, value, receiver) should set the property of a writable, configurable property of target .

If target already has an own non-configurable property with name propKey , then a TypeError should be thrown since the property can’t be set.

setPrototypeOf(target, proto) ‘s returned result is coerced into a boolean.

If the target isn’t extensible, then its prototype can’t be changed.

In this case, target ‘s prototype must be the same as what it is now, or a TypeError would be thrown.

Photo by Luke Stackpoole on Unsplash

Conclusion

The proxy handler methods must follow some conditions even though it lets us customize those operations.

This way, the object operations are still predictable.

Enjoyed this article? If so, get more similar content by subscribing to Decoded, our YouTube channel!