首页ES6 Proxy的API介绍及应用场景
Created At : 2021-11-19
# ES6 Proxy的API介绍及应用场景
Proxy的语法非常简单,所有的Proxy示例都是基于以下语法:
/***
* target
* 要使用 Proxy 包装的目标对象(可以是任何类型的对象,包括原生数组,函数,甚至另一个代理)。
* handler
* 一个通常以函数作为属性的对象,各属性中的函数分别定义了在执行各种操作时代理 p 的行为。
* p
* Proxy的实例
*/
const p = new Proxy(target, handler)
基础示例
基于以上语法先创建一个示例:
//1: 定义一个target,名称随意,如 person
const person = {
name: 'Jack'
};
//2:创建一个handler,名称随意,这里就叫handler
const handler = {
//trap,提供属性访问的方法
get(target, property) {
console.log(`正在读取属性: ${property}`);
return "Jack Ma"
}
};
//3: 通过构造函数创建一个Proxy实例proxyPerson
const proxyPerson = new Proxy(person, handler);
console.log(proxyPerson.name); //Jack Ma
console.log(person.name); //Jack, 针对target对象本身操作,没有任何效果
//------------------------------结果如下:
正在读取属性: name
Jack Ma
Jack
⚡ 从以上示例可知:
- 要使得
Proxy
起作用,必须针对Proxy
实例(上例是proxyPerson
对象)进行操作,而不是针对目标对象(person)进行操作。 - Proxy实例对象代理了person的所有属性。
- 对Proxy实例对象的读操作(proxyPerson.name),会被handler中的get进行监听和拦截,并可以改变其值,如本例,将
Jack
改为Jack Ma
1.get() Trap
当访问指定属性时触发,例如上面的基础示例。
//拦截对象属性的读取,比如proxy.foo和proxy['foo']
get(target, propKey, receiver)
get() trap应用示例1:创建私有属性
通常作为约定,以_
开头的变量为对象的私有属性,不能访问,但是在JavaScript中,这只是开发上约束,并不能阻止用户真正的访问。
比如:
const person = {
dateOfBirth: '2003-11-11',
//_age属性为私有属性,其值应该通过dateOfBirth进行计算
_age: 18
}
person._age //用户还是可以访问
但是,通过get() trap我们可以实现阻止用户对私有属性的读取或赋值操作:
const person = {
dateOfBirth: '2003-11-11',
//_age属性为私有属性,其值应该通过dateOfBirth进行计算
_age: 18
}
const handler = {
get: function(target, key) {
if (key[0] === '_') {
throw new Error('Attempt to access private property');
}
return target[key];
},
set: function(target, key, value) {
if (key[0] === '_') {
throw new Error('Attempt to access private property');
}
target[key] = value;
}
};
const p = new Proxy(person,handler)
//访问_age,会抛出异常, 同样,为其赋值也会抛出异常。
//Error: Attempt to access private property
p._age
2.set() Trap
用法同get,不过是在赋值是触发。例如上例中的 p._age = 18
//拦截对象属性的设置,比如proxy.foo = v或proxy['foo'] = v,返回一个布尔值。
//target: The target object that the proxy attached to
//property: The name of the property being set
//value: The value which is assigned to the property
set(target, propKey, value, receiver)
应用示例:
const person = {
score: 60
}
const handler = {
set: function(target, key, value) {
if (key === 'score') {
if (!(typeof value === 'number')) {
throw new Error('分数应该是数字');
}
if (value < 0 || value > 150) {
throw new Error("分数不能低于0或高于150");
}
}
console.log("当前分数为:",value)
target[key] = value;
}
};
const p = new Proxy(person,handler)
p.score = 100 // OK,当前分数为: 100
p.score = 200 // throw new Error,Error: 分数不能低于0或高于150