DEV Community

Play Button Pause Button
Caleb Weeks
Caleb Weeks

Posted on

Fun with JavaScipt proxies: observability, extensible chaining, and callable objects

I've been having a lot of fun playing with JavaScript proxies lately. It is fun to come up with creative ways of using them. In today's JavaScript meetup, we took a look at using proxies to handle obversability, create chainable APIs, and define callable objects.

The code for the proxies discussion can be found below and here

const helpers = require("./helpers"); const { log } = helpers; // Proxies provide transparent obeservability const array = [1, 2, 3, 4, 5, 6, 7, 8, 9]; const proxy = new Proxy(array, {}); log(array, proxy); log(typeof array, typeof proxy); log( Object.getOwnPropertyNames(array), Object.getOwnPropertyNames(proxy) ); //////// Observability //////// const onUpdate = (obj) => (callback) => { return new Proxy(obj, { set: (_target, _prop, value) => { callback(value); Reflect.set(...arguments); }, }); }; const person = onUpdate({ firstName: "George", lastName: "Washington", })(log); person.lastName = "Clooney"; //////// Chaining outside functions //////// const chain = (fns) => (obj) => { const isFunction = (fn) => typeof fn === "function"; const chainify = (obj) => { if (typeof obj === "object" && obj !== null) { return new Proxy(obj, { get: (target, prop) => { switch (true) { case isFunction(target[prop]): return (...args) => chainify(target[prop].apply(target, args)); case isFunction(fns[prop]): return (...args) => chainify(fns[prop].apply(target, [target, ...args])); default: return target[prop]; } }, }); } return obj; }; return chainify(obj); }; chain(helpers)(array) .map((i) => i + 10) .log() .shuffle() .log() .zipWith(["a", "b", "c", "d", "e"], (a, b) => a + b) .log(); //////// Call object as a function //////// const callable = (obj) => new Proxy(() => {}, { apply(_target, _, [prop, ...args]) { return obj[prop] || obj._(prop); }, }); const fib = callable({ 0: 1, 1: 1, _: (n) => fib(n - 1) + fib(n - 2), }); chain({ fib, log })(array) .map((i) => fib(i)) .log(); 
Enter fullscreen mode Exit fullscreen mode

Top comments (1)

Collapse
 
artydev profile image
artydev

Great thank you