2023-10-27 21:16:03
JavaScript中的代理模式通过Proxy构造函数实现对象访问控制,其核心是利用拦截器(handler)对象监听并干预目标对象的操作,从而在不修改原对象的前提下实现权限校验、数据验证或行为限制。 以下是具体实现方式及示例:
1. 基础拦截:限制敏感属性访问通过拦截get和set方法,可限制对特定属性(如密码)的读写操作:
const user = { name: 'Alice', password: 'secret123' };const proxyUser = new Proxy(user, { get(target, property) { if (property === 'password') { console.warn('访问被拒绝:密码是私有信息'); return undefined; // 拒绝读取 } return target[property]; }, set(target, property, value) { if (property === 'password' && value.length < 6) { console.error('密码长度不能少于6位'); return false; // 拒绝写入 } target[property] = value; return true; }});// 测试console.log(proxyUser.password); // 警告并返回undefinedproxyUser.password = '123'; // 错误并阻止设置2. 实现只读对象通过拦截set和deleteProperty方法,禁止修改或删除属性:
function createReadOnly(target) { return new Proxy(target, { set() { console.error('该对象为只读,无法修改'); return false; }, deleteProperty() { console.error('无法删除属性'); return false; } });}const config = createReadOnly({ api: '利用ownKeys和has方法过滤以特定前缀(如_)开头的私有属性:
const obj = { name: 'Bob', _secret: 'hidden' };const filtered = new Proxy(obj, { ownKeys(target) { return Object.keys(target).filter(key => !key.startsWith('_')); }, has(target, key) { if (key.startsWith('_')) return false; // 隐藏属性 return key in target; }});console.log(Object.keys(filtered)); // 输出: ['name']console.log('_secret' in filtered); // 输出: false4. 其他拦截方法的应用apply:代理函数调用,适用于函数对象的访问控制。
const sum = (a, b) => a + b;const proxySum = new Proxy(sum, { apply(target, thisArg, args) { if (args.some(arg => typeof arg !== 'number')) { throw new Error('参数必须为数字'); } return target.apply(thisArg, args); }});proxySum(1, 2); // 正常执行proxySum(1, 'a'); // 抛出错误construct:拦截new操作符,控制构造函数调用。
class User { constructor(name) { this.name = name; }}const proxyUser = new Proxy(User, { construct(target, args) { if (args[0].length < 3) { throw new Error('用户名长度不能少于3位'); } return new target(...args); }});new proxyUser('Al'); // 抛出错误new proxyUser('Alice'); // 正常创建权限管理:限制敏感数据访问(如密码、身份信息)。
数据验证:确保属性值符合规则(如长度、类型)。
调试监控:记录对象操作日志(如记录属性修改历史)。
API封装:隐藏内部实现细节,提供更安全的接口。
通过合理设计handler中的陷阱函数,Proxy可实现高度定制化的对象访问控制,是JavaScript中强大的元编程工具。