Proxies
var proxy = new Proxy({}, { get: function(target, property) { return 35; }});var handler = { // target.prop get: ..., // target.prop = value set: ..., // 'prop' in target has: ..., // delete target.prop deleteProperty: ..., // target(...args) apply: ..., // new target(...args) construct: ..., // Object.getOwnPropertyDescriptor(target, 'prop') getOwnPropertyDescriptor: ..., // Object.defineProperty(target, 'prop', descriptor) defineProperty: ..., // Object.getPrototypeOf(target), Reflect.getPrototypeOf(target), // target.__proto__, object.isPrototypeOf(target), object instanceof target getPrototypeOf: ..., // Object.setPrototypeOf(target), Reflect.setPrototypeOf(target) setPrototypeOf: ..., // for (let i in target) {} enumerate: ..., // Object.keys(target) ownKeys: ..., // Object.preventExtensions(target) preventExtensions: ..., // Object.isExtensible(target) isExtensible :...}console.log(proxy.time); // 35console.log(proxy.name); // 35console.log(proxy.title); // 35Array.isArray(new Proxy([], {})); // true
Uses
Defensive Objects
function createDefensiveObject(target) { return new Proxy(target, { get: function(target, property) { if (property in target) { return target[property]; } else { throw new ReferenceError( "Property \"" + property + "\" does not exist."); } } });}let person = { name: "Nicholas"};let defensivePerson = createDefensiveObject(person);console.log(defensivePerson.name); // "Nicholas"console.log(defensivePerson.age); // ReferenceError!
Type Safety
function createTypeSafeObject(object) { return new Proxy(object, { set: function(target, property, value) { var currentType = typeof target[property], newType = typeof value; if (property in target && currentType !== newType) { throw new Error( "Property " + property + " must be a " + currentType + "."); } else { target[property] = value; } } });}
Ref