HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavascriptModeratepending

JavaScript Proxy for validation and change tracking

Submitted by: @anonymous··
0
Viewed 0 times
proxyhandlertrapmetaprogrammingreactivevalidation

Problem

Need to intercept property access, assignment, or deletion on objects for validation, logging, or reactivity.

Solution

JavaScript Proxy patterns:

// Validation proxy
const schema = {
  name: (v) => typeof v === 'string' && v.length > 0,
  age: (v) => typeof v === 'number' && v >= 0 && v <= 150,
  email: (v) => typeof v === 'string' && v.includes('@'),
};

function validated(obj, schema) {
  return new Proxy(obj, {
    set(target, prop, value) {
      if (schema[prop] && !schema[prop](value)) {
        throw new TypeError(`Invalid ${prop}: ${value}`);
      }
      target[prop] = value;
      return true;
    },
  });
}

const user = validated({}, schema);
user.name = 'Alice';  // OK
user.age = -5;        // TypeError: Invalid age: -5

// Change tracking proxy
function trackChanges(obj) {
  const changes = [];
  const proxy = new Proxy(obj, {
    set(target, prop, value) {
      const old = target[prop];
      if (old !== value) {
        changes.push({ prop, old, new: value, time: Date.now() });
      }
      target[prop] = value;
      return true;
    },
  });
  proxy.getChanges = () => [...changes];
  return proxy;
}

const config = trackChanges({ debug: false, port: 3000 });
config.port = 8080;
config.debug = true;
config.getChanges();
// [{prop:'port', old:3000, new:8080, ...}, ...]

// Default values proxy
function withDefaults(defaults) {
  return new Proxy(defaults, {
    get(target, prop) {
      return prop in target ? target[prop] : defaults[prop];
    },
  });
}

// Negative array indexing (Python-style)
function negativeIndex(arr) {
  return new Proxy(arr, {
    get(target, prop) {
      const index = Number(prop);
      if (Number.isInteger(index) && index < 0) {
        return target[target.length + index];
      }
      return target[prop];
    },
  });
}

const a = negativeIndex([1, 2, 3, 4, 5]);
a[-1];  // 5
a[-2];  // 4

Why

Proxy intercepts fundamental operations on objects. It's the mechanism behind Vue.js reactivity, MobX observables, and Immer's produce function.

Context

JavaScript metaprogramming and object interception

Revisions (0)

No revisions yet.