hand
_1_11_198
4
返回栏目
0k
2k
1k
2k
1k
1k
1k
2k
2k
2k
1k
2k
1k
2k
1k
1k
1k
1k
1k
2k
1k
1k
1k
1k
1k
1k
1k
1k
1k
2k
1k
1k
1k
1k
1k
1k
1k
1k
1k
2k
1k
1k
1k
1k
1k
1k
1k
2k
1k
2k
1k
1k
1k
1k
1k
1k
1k
2k
2k
1k
1k
1k
2k
1k
1k
2k
2k
1k
1k
1k
2k
1k
1k
2k
2k
1k
2k
1k
1k
2k
2k
2k
3k
3k
2k
3k
2k
3k
3k
3k
1k
2k
3k
2k
2k
3k
3k
2k
2k
6k
3k
2k
2k
5k
3k
4k
3k
3k
2k
4k
3k
3k
2k
3k
3k
1k
4k
4k
4k
2k
5k
3k
2k
3k
4k
3k
3k
4k
2k
3k
3k
4k
2k
2k
3k
4k
3k
3k
2k
5k
2k
3k
3k
3k
3k
2k
3k
3k
3k
2k
2k
2k
2k
3k
2k
2k
2k
3k
2k
2k
2k
2k
2k
2k
0.1k
0.2k
3k
2k
3k
2k
0.1k
2k
2k
4k
2k
2k
1k
2k
2k
3k
3k
3k
3k
2k
2k
3k
3k
3k
4k
3k
3k
4k
3k
2k
2k
3k
3k
3k
3k
3k
3k
2k
3k
3k
4k
4k
3k
3k
2k
2k
3k
2k
2k
1k
2k
3k
1k
2k
2k
2k
2k
2k
2k
2k
2k
2k
4k
2k
3k
2k
1k
2k
2k
2k
2k
2k
3k
2k
3k
1k
2k
2k
2k
0k
2k
2k
2k
2k
2k
2k
2k
3k
2k
2k
1k
1k
3k
2k
3k
1k
2k
1k
2k
2k
2k
2k
3k
1k
3k
2k
2k
2k
2k
2k
2k
1k
2k
2k
4k
3k
3k
2k
2k
2k
2k
2k
2k
4k
3k
3k
3k
2k
2k
2k
2k
2k
2k
3k
4k
返回前端 - Javascript栏目
作者:
贺及楼
成为作者
更新日期:2025-02-21 20:44:38
在 JavaScript 中,Proxy 对象是一个强大的特性,它允许我们拦截并重新定义对象的基本操作,如属性查找、赋值、枚举、函数调用等。这一特性为我们提供了很多有趣且实用的应用场景,下面我们就来详细探讨 Proxy 对象的各种应用场景。
在实际开发中,我们经常需要对对象的属性值进行验证,确保其符合特定的规则。使用 Proxy 可以方便地实现这一功能。
const validator = {
set: function (obj, prop, value) {
if (prop === 'age') {
if (typeof value!== 'number' || value < 0) {
throw new TypeError('Age must be a positive number');
}
}
// 正常设置属性值
obj[prop] = value;
return true;
}
};
const person = new Proxy({}, validator);
try {
person.age = 25;
console.log(person.age); // 输出: 25
person.age = -1; // 抛出错误
} catch (error) {
console.error(error.message);
}
在上述代码中,我们创建了一个 Proxy 对象 person
,并通过 validator
拦截了对象属性的赋值操作。当尝试给 age
属性赋值时,会先检查值是否为正数,如果不是则抛出错误。
JavaScript 本身没有真正意义上的私有属性,但可以使用 Proxy 来模拟私有属性的行为。
const createPrivateObject = () => {
const privateData = new WeakMap();
const handler = {
get: function (obj, prop) {
const data = privateData.get(obj);
if (data && data.hasOwnProperty(prop)) {
return data[prop];
}
return obj[prop];
},
set: function (obj, prop, value) {
if (prop.startsWith('_')) {
let data = privateData.get(obj);
if (!data) {
data = {};
privateData.set(obj, data);
}
data[prop] = value;
} else {
obj[prop] = value;
}
return true;
}
};
const target = {};
return new Proxy(target, handler);
};
const myObject = createPrivateObject();
myObject._privateProp = 'secret';
myObject.publicProp = 'visible';
console.log(myObject.publicProp); // 输出: visible
console.log(myObject._privateProp); // 输出: undefined
在这个例子中,我们通过 WeakMap
存储私有数据,当属性名以 _
开头时,将其视为私有属性,外部无法直接访问。
对于一些计算开销较大的函数,我们可以使用 Proxy 来实现缓存机制,避免重复计算。
const cache = new Map();
const createCachedFunction = (func) => {
const handler = {
apply: function (target, thisArg, args) {
const key = args.join(',');
if (cache.has(key)) {
return cache.get(key);
}
const result = func.apply(thisArg, args);
cache.set(key, result);
return result;
}
};
return new Proxy(func, handler);
};
const expensiveFunction = (a, b) => {
console.log('Performing expensive calculation...');
return a + b;
};
const cachedFunction = createCachedFunction(expensiveFunction);
console.log(cachedFunction(2, 3)); // 输出: Performing expensive calculation... 5
console.log(cachedFunction(2, 3)); // 直接从缓存中获取结果,输出: 5
这里我们创建了一个代理函数 cachedFunction
,在调用时会先检查缓存中是否已经有结果,如果有则直接返回,否则进行计算并将结果存入缓存。
使用 Proxy 可以方便地记录对象属性的访问和修改操作,有助于调试和监控。
const logHandler = {
get: function (obj, prop) {
console.log(`Getting property ${prop}`);
return obj[prop];
},
set: function (obj, prop, value) {
console.log(`Setting property ${prop} to ${value}`);
obj[prop] = value;
return true;
}
};
const targetObject = { name: 'John', age: 30 };
const loggedObject = new Proxy(targetObject, logHandler);
loggedObject.name; // 输出: Getting property name
loggedObject.age = 31; // 输出: Setting property age to 31
通过这种方式,我们可以清晰地看到对象属性的访问和修改过程。
应用场景 | 描述 | 示例代码 |
---|---|---|
数据验证 | 拦截属性赋值操作,确保属性值符合特定规则 | 验证 age 属性为正数 |
私有属性模拟 | 模拟私有属性,外部无法直接访问 | 以 _ 开头的属性视为私有属性 |
缓存机制 | 避免重复计算,提高性能 | 缓存函数的计算结果 |
日志记录 | 记录对象属性的访问和修改操作,方便调试和监控 | 记录 name 和 age 属性的操作 |
Proxy 对象为 JavaScript 开发提供了强大的元编程能力,通过合理运用 Proxy,我们可以实现各种有趣且实用的功能,提升代码的可维护性和性能。
前端 - Javascript
整章节共299节
快分享给你的小伙伴吧 ~