发布于 2026-01-06 6 阅读
0

时隔多年,终于发现了 JavaScript 代理的强大之处

时隔多年,终于发现了 JavaScript 代理的强大之处

作为一名从事 JavaScript 开发超过 25 年的工程师,我自认为已经见识过所有的一切。我精通回调函数,熟悉 Promise,甚至驯服了强大的 async/await。然而,有一天,我偶然发现了一个我从未用过的隐藏瑰宝:JavaScript 代理。

我花了四分之一世纪才发现这个功能强大且用途广泛的特性,它一直静静地躺在那里,等待着被发掘。所以,如果你也像我一样,这些年来一直忽略了 JavaScript 代理,那么请允许我向你展示一些有趣的用例,它们或许会改变你编写 JavaScript 的方式。

1. 验证

你是否曾经觉得需要对对象的属性进行限制,以确保数据完整性?使用代理,你可以在设置属性值时添加验证检查。这就像为你的数据配备了一个私人保镖!

const validationHandler = {
  set: function (target, property, value) {
    if (property === 'age' && (typeof value !== 'number' || value <= 0)) {
      throw new TypeError('Age must be a positive number');
    }
    target[property] = value;
    return true;
  },
};

const person = new Proxy({}, validationHandler);
person.age = 25; // OK
person.age = -5; // Throws TypeError
Enter fullscreen mode Exit fullscreen mode

2. 日志记录和性能分析

调试常常感觉像是大海捞针。为什么不让代理来帮你记录或分析对象的操作呢?这就像拥有你自己的私人侦探一样!

const loggingHandler = {
  get: function (target, property) {
    console.log(`Getting ${property}`);
    return target[property];
  },
  set: function (target, property, value) {
    console.log(`Setting ${property} to ${value}`);
    target[property] = value;
    return true;
  },
};

const loggedObject = new Proxy({}, loggingHandler);
loggedObject.foo = 42; // Logs: "Setting foo to 42"
console.log(loggedObject.foo); // Logs: "Getting foo" and 42
Enter fullscreen mode Exit fullscreen mode

3. 门禁控制

通过强制执行访问控制,像保护诺克斯堡一样保护对象的属性。使用代理,您可以将某些属性设置为只读,或根据特定条件限制访问。这就像拥有一个坚不可摧的安全系统!

const readOnlyHandler = {
  set: function (target, property, value) {
    if (property === 'readOnly') {
      throw new Error('Cannot modify read-only property');
    }
    target[property] = value;
    return true;
  },
};

const protectedObject = new Proxy({ readOnly: true }, readOnlyHandler);
protectedObject.newProperty = 'some value'; // OK
protectedObject.readOnly = false; // Throws Error
Enter fullscreen mode Exit fullscreen mode

4. 延迟加载

何必一开始就做那么多苦差事,不如轻松点?代理可以让你实现对象属性的延迟加载,只在实际访问时才计算或获取值。这就像拥有一个私人助理来管理你的工作量!

const lazyLoadHandler = {
  get: function (target, property) {
    if (!target[property]) {
      target[property] = expensiveComputation();
    }
    return target[property];
  },
};

const lazyLoadedObject = new Proxy({}, lazyLoadHandler);
const result = lazyLoadedObject.expensiveProperty; // Calls expensiveComputation() on first access
Enter fullscreen mode Exit fullscreen mode

5. 计算属性

通过创建计算属性,将您的对象变成聪明的数学家。代理允许您根据其他属性计算值,使您的对象更智能、更灵活。就像拥有一个内置计算器一样!

const computedHandler = {
  get: function (target, property) {
    if (property === 'fullName') {
      return `${target.firstName} ${target.lastName}`;
    }
    return target[property];
  },
};

const user = new Proxy({ firstName: 'John', lastName: 'Doe' }, computedHandler);
console.log(user.fullName); // Logs: "John Doe"
Enter fullscreen mode Exit fullscreen mode

好了,各位!作为一名 JavaScript 爱好者,25 年来我终于领略到了JavaScript Proxy (MDN)的强大功能和多功能性。学习新知识,为你的开发工具箱增添一件利器,永远都不晚!

现在轮到你了!你在项目中是如何使用 JavaScript Proxy 的?请在下方评论区分享你的创意和创新案例。让我们一起开启 Proxy 之旅,看看它会带我们去向何方!

文章来源:https://dev.to/marclipovsky/discovering-the-power-of-javascript-proxy-after-all-this-time-4627