proxy
Proxy 对象用于创建一个对象的代理,从而实现基本操作的拦截和自定义(如属性查找、赋值、枚举、函数调用等)。
const p=new Proxy(target,handler)
局限性
内建对象:内部插槽
内建方法可以直接访问内建对象,而不通过[[Get]]/[[Set]]内部方法,所以无法拦截。
let map=new Map()
let proxy=new Proxy(map,{})
proxy.set('test','内建插槽')
原因是:Map将项目存储在[[MapData]]内部插槽中。代理对象没有这种插槽。Map.prototype.set方法视图访问内部属性this.[[MapData]],但是this=proxy。
私有字段
在 JavaScript 中,私有字段通常是指以双下划线 __ 开头的属性。Proxy 可以拦截对象上的任何操作,包括对私有字段的访问和修改。例如,可以使用 Proxy 拦截对象上的 get 和 set 操作,来实现对私有字段的拦截。
以下是一个使用 Proxy 拦截私有字段的示例:
const obj = {
__privateField: 'private value'
};
const handler = {
get(target, prop) {
if (prop.startsWith('__')) {
throw new Error('Private field access denied.');
}
return target[prop];
},
set(target, prop, value) {
if (prop.startsWith('__')) {
throw new Error('Private field modification denied.');
}
target[prop] = value;
return true;
}
};
const proxy = new Proxy(obj, handler);
console.log(proxy.publicField); // undefined
console.log(proxy.__privateField); // 抛出异常:Private field access denied.
proxy.publicField = 'new value';
proxy.__privateField = 'new private value'; // 抛出异常:Private field modification denied.
定义了一个包含私有字段的对象 obj,并使用 Proxy 来拦截对私有字段的访问和修改。在 get 和 set 处理函数中,检查了属性名是否以 __ 开头,如果是,则抛出异常;否则,执行默认操作。这样,就可以实现对私有字段的拦截,从而提高了代码的安全性和可维护性。
兼容问题
如:
- IE11 及其以下版本的 Internet Explorer 浏览器不支持 Proxy。
- Android 4.4 及其以下版本的 Android 系统不支持 Proxy。
- 部分国产手机系统,如华为 EMUI 等,可能会限制某些 ES6 特性的使用,包括 Proxy。