Skip to content

Instantly share code, notes, and snippets.

@crazy4groovy
Last active September 2, 2020 21:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save crazy4groovy/7450cc6e81e2c4f3500b673d464dad94 to your computer and use it in GitHub Desktop.
Save crazy4groovy/7450cc6e81e2c4f3500b673d464dad94 to your computer and use it in GitHub Desktop.
Metaprogramming with Proxies
// https://exploringjs.com/deep-js/ch_proxies.html#proxy-use-cases
const propertyCheckerHandler = {
get(target, propKey, receiver) {
// Only check string property keys
if (typeof propKey === 'string' && !(propKey in target)) {
throw new ReferenceError('Unknown property: ' + propKey);
}
return Reflect.get(target, propKey, receiver);
}
};
const PropertyChecker = new Proxy({}, propertyCheckerHandler);
// Let’s use PropertyChecker for an object:
const jane = {
__proto__: PropertyChecker,
name: 'Jane',
};
// Own property:
assert.equal(jane.name, 'Jane');
// Typo:
assert.throws(() => jane.nmae, /^ReferenceError: Unknown property: nmae$/);
// Inherited property:
assert.equal(jane.toString(), '[object Object]');
// If we turn PropertyChecker into a constructor, we can use it for classes via extends:
// We can’t change .prototype of classes, so we are using a function
function PropertyCheckerBase() {}
PropertyCheckerBase.prototype = new Proxy({}, propertyCheckerHandler);
class Point extends PropertyCheckerBase {
constructor(x, y) {
super();
this.x = x;
this.y = y;
}
}
const point = new Point(5, 7);
assert.equal(point.x, 5);
assert.throws(() => point.z, /^ReferenceError: Unknown property: z/);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment