JAVA SCRIPT - Implementing Just-in-Time Object Behavioral Modifications with Proxies - Web Development and Design | Tutorial for Java, PHP, HTML, Javascript JAVA SCRIPT - Implementing Just-in-Time Object Behavioral Modifications with Proxies - Web Development and Design | Tutorial for Java, PHP, HTML, Javascript

Breaking

Post Top Ad

Post Top Ad

Thursday, March 7, 2019

JAVA SCRIPT - Implementing Just-in-Time Object Behavioral Modifications with Proxies

 Implementing Just-in-Time Object Behavioral Modifications with Proxies


Problem

You want to attach behavior to an object, such as ensuring proper data types for values or log when an object changes, but you want to do so transparently

Solution

Use the ES 6 Proxy to attach the desired behavior to the targeted action. To ensure that only given properties are set on an object and that a number property for an object is given an actual number, not a string or other value that can’t be converted to a number, use a Proxy to test the value when it’s set on the object:


function propChecker(target) {
 return Proxy(target, {
 set: function(target, property, value) {
 if (property == 'price') {
 if (typeof value != 'number') {
 throw new TypeError("price is not a number");
 } else if (value <= 0) {
 throw new RangeError("price must be greater than zero");
 }
 } else if (property != 'name') {
 throw new ReferenceError("property '" + property + "' not valid");
 }
 target[property] = value;
 }
 });
}
function Item() {
 return propChecker(this);
}
try {
 var keyboard = new Item();
 keyboard.name = "apple"; // OK
 keyboard.type = "red delicious"; // throws ReferenceError
 keyboard.price = "three dollars"; // throws TypeError
 keyboard.price = -1.00; // throws RangeError
} catch(err) {
 console.log(err.message);
}


EXPLAIN

The Proxy object wraps an object and can be used to trap specific actions, and then provide additional or alternative behaviors based on both the actions and the object’s data at the time of the action. The Mozilla Developer Network documentation for the object refers to the capability as meta-programming API. 

In the solution, because we want to modify what happens when properties are set on the target object, and the target objects are themselves instances, the proxy of the object is returned, rather than the object directly, in the constructor. This is accomplished by passing this as the target object for the Proxy call, and then defining a handler function, propChecker, for the object. 

In the handler, we’re only interested in altering the semantics of the set operation. The function used to handle the operation is passed the target object, the property, and the new property value.

 In the function, the code tests to see if the property being set is price, and if so, it then checks to see if it’s a Number. If it isn’t, a TypeError is thrown. If it is, then the value is checked to make sure it’s greater than zero. If it’s not, then a RangeError is thrown.

Finally, the property is checked to see if it’s name, instead. If it isn’t, the final error, a ReferenceError, is thrown. If none of the error conditions is triggered, then the property is assigned the value. .

Based on all of this, new instances of the target object can only have the two properties set, and the numeric property must be a number greater than zero.

Proxy supports a considerable number of traps, which I’ve listed in Table 10-1. The table lists the API trap, followed by the parameters the handler function expects, expected return value, and how it’s triggered. These are all pulled directly from the Harmony documentation, as it’s the most current listing at this time. The important point to keep in mind is that each of these is a trap that you can trigger and redefine the semantics of. 

Proxies can also wrap JavaScript built-in objects, such as Arrays, or even the Date object. In the following code, a proxy is used to redefine the semantics of what happens when the code accesses an array. The get passes the target, name, and receiver to the proxy handling function. The value of the array at the given index is checked and if it’s a value of zero (0), a value of false is returned; otherwise, a value of true is returned: 

var handler = {
 get: function(arry, indx){
 if (arry[indx] === 0) {
 return false;
 } else {
 return true;
 }
 }
};
var arr = [1,0,6,1,1,0];
var a = new Proxy(arr, handler);
console.log(a[2]); // true
console.log(a[0]); // true
console.log(a[1]); // false


The array value at an index of 2 is not zero, so true is returned. The same is true for the value at an index of zero. However, the value at the index of 1 is zero, so false is returned. This behavior holds anytime this array proxy is accessed

No comments:

Post a Comment

Post Top Ad