教你如何创建自己的网站,建设部网站上就能查,网络公关公司联系方式,帝国cms制作网站地图Proxy 是 ES6 引入的一种强大的拦截机制#xff0c;用于定义对象的基本操作#xff08;如读取、赋值、删除等#xff09;的自定义行为。相较于 Object.defineProperty#xff0c;Proxy 提供了更灵活、全面的拦截能力。 1. Proxy 语法
const proxy new Proxy(target, hand…Proxy 是 ES6 引入的一种强大的拦截机制用于定义对象的基本操作如读取、赋值、删除等的自定义行为。相较于 Object.definePropertyProxy 提供了更灵活、全面的拦截能力。 1. Proxy 语法
const proxy new Proxy(target, handler);target被代理的对象handler定义拦截行为的对象 2. Proxy 基本用法
(1) 拦截对象的属性访问
const person {name: Alice,age: 25,
};const proxyPerson new Proxy(person, {get(target, prop) {console.log(访问属性: ${prop});return prop in target ? target[prop] : 属性不存在;},
});console.log(proxyPerson.name); // 访问属性: name - Alice
console.log(proxyPerson.gender); // 访问属性: gender - 属性不存在(2) 拦截对象的属性修改
const proxyPerson new Proxy(person, {set(target, prop, value) {if (prop age typeof value ! number) {throw new Error(年龄必须是数字);}target[prop] value;console.log(设置 ${prop} 为 ${value});return true;},
});proxyPerson.age 30; // 设置 age 为 30
proxyPerson.age abc; // 抛出错误: 年龄必须是数字(3) 拦截对象的属性删除
const proxyPerson new Proxy(person, {deleteProperty(target, prop) {console.log(删除属性: ${prop});return delete target[prop];},
});delete proxyPerson.age; // 删除属性: age(4) 拦截 in 操作符 (has 方法)
const proxyPerson new Proxy(person, {has(target, prop) {console.log(检查属性是否存在: ${prop});return prop in target;},
});console.log(name in proxyPerson); // 检查属性是否存在: name - true
console.log(gender in proxyPerson); // 检查属性是否存在: gender - falseconst range { start: 10, end: 50 };const proxy new Proxy(range, {has(target, prop) {return prop target.start prop target.end;}
});console.log(15 in proxy); // true
console.log(60 in proxy); // false(5) 拦截函数调用 (apply 方法)
const multiply new Proxy((a, b) a * b, {apply(target, thisArg, args) {console.log(调用函数 multiply参数: ${args});return target(...args);}
});console.log(multiply(3, 4)); // 调用函数 multiply参数: 3,4 - 12(6) 拦截构造函数 (construct 方法)
const Person new Proxy(class {constructor(name) {this.name name;}
}, {construct(target, args) {console.log(创建实例参数: ${args});return new target(...args);}
});const user new Person(Alice); // 创建实例参数: Alice特点
可以 监听整个对象而不是单个属性。能拦截 所有操作如 get、set、has、deleteProperty、apply 等。可以用于 动态代理使得代码更具扩展性。 3. Proxy 实际使用场景
(1) 数据验证和格式化
const user new Proxy({}, {set(target, prop, value) {if (prop age typeof value ! number) {throw new Error(年龄必须是数字);}target[prop] value;return true;}
});(2) 实现私有属性和方法
const createUser () {const privateData new WeakMap();return new Proxy({}, {get(target, prop) {if (prop.startsWith(_)) {throw new Error(无法访问私有属性);}return target[prop];}});
};(3) 添加日志记录和调试功能
const logger new Proxy({}, {get(target, prop) {console.log(访问属性: ${prop});return target[prop];}
});(4) 提供默认值和只读访问
const defaultSettings new Proxy({}, {get(target, prop) {return prop in target ? target[prop] : 默认值;},set() {throw new Error(设置操作被禁止);}
});(5) 实现惰性加载和缓存
const lazyObject new Proxy({}, {get(target, prop) {if (!(prop in target)) {console.log(初始化 ${prop});target[prop] prop.toUpperCase();}return target[prop];}
});(6) 解决 this 指向问题
const obj {name: Alice,greet() {return Hello, ${this.name};}
};const proxyObj new Proxy(obj, {get(target, prop, receiver) {return typeof target[prop] function ? target[prop].bind(target) : target[prop];}
});const greet proxyObj.greet;
console.log(greet()); // Hello, Alice4.Object.defineProperty
Object.defineProperty() 允许直接在对象上定义新的属性或者修改已有属性的特性如可读写性、是否可枚举等。
示例
const person {};Object.defineProperty(person, name, {value: Alice,writable: false, // 不能修改enumerable: true,configurable: false
});console.log(person.name); // Alice
person.name Bob; // 失败严格模式下会报错
console.log(person.name); // Alice特点
只能加工 单个属性不能监听整个对象。只能 定义静态的行为不能动态处理对象属性的操作。不能拦截 删除、新增属性 或 函数调用。 5. Proxy 与 Object.defineProperty 详细对比
特性Object.definePropertyProxy监听属性读取❌ 不支持✅ 支持 (get)监听属性赋值✅ 支持 (set)✅ 支持 (set)监听属性删除❌ 不支持✅ 支持 (deleteProperty)监听属性存在性❌ 不支持✅ 支持 (has) (in 关键字)监听对象新增属性❌ 不支持✅ 支持 (set)监听函数调用❌ 不支持✅ 支持 (apply)监听构造函数❌ 不支持✅ 支持 (construct)监听整个对象❌ 需要对每个属性定义✅ 一次性监听整个对象适用于数组或集合❌ 不适合✅ 适合可扩展性❌ 需手动定义✅ 更强大支持代理嵌套