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); // 35
console.log(proxy.name); // 35
console.log(proxy.title); // 35
Array.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