object.defineProperty 和 proxy 的区别
文章类型:Javascript
发布者:hp
发布时间:2025-04-13
只能拦截对象属性的读取(get)和设置(set)。
只能对已知属性进行拦截,无法拦截新增属性或删除属性。
可以拦截对象的多种操作,包括属性读取(get)、设置(set)、删除(deleteProperty)、枚举(enumerate)、函数调用(apply)等。
可以拦截未知属性的操作,支持动态属性的拦截。
需要针对每个属性单独设置拦截器。
修改对象的现有行为,而不是创建一个新对象
创建一个代理对象,拦截对目标对象的所有操作。
不修改原对象,而是返回一个新的代理对象
仅支持 get 和 set 拦截。无法拦截以下操作:属性的删除(delete)。属性的枚举(for...in 或 Object.keys)。新增属性。
支持多种操作的拦截,包括:get:读取属性。set:设置属性。deleteProperty:删除属性。has:in 操作符。ownKeys:Object.keys、for...in 等。apply:函数调用(当代理目标是函数时)。
性能较好,适合对少量属性进行拦截。
但如果需要对大量属性进行拦截,代码会变得冗长且难以维护
性能略低于 Object.defineProperty,因为需要处理更多的拦截操作。
但在需要拦截多种操作或动态属性的场景下,Proxy 的性能优势更明显
const obj = {};
Object.defineProperty(obj, 'name', {
get() {
console.log('读取 name 属性');
return this._name;
},
set(value) {
console.log('设置 name 属性');
this._name = value;
},
});
obj.name = 'Alice'; // 设置 name 属性
console.log(obj.name); // 读取 name 属性
const target = {};
const proxy = new Proxy(target, {
get(obj, prop) {
console.log(`读取 ${prop} 属性`);
return obj[prop];
},
set(obj, prop, value) {
console.log(`设置 ${prop} 属性`);
obj[prop] = value;
return true;
},
});
proxy.name = 'Alice'; // 设置 name 属性
console.log(proxy.name); // 读取 name 属性