Proxy 这个词的原意是代理,用在这里表示由它来“代理”某些操作,可以译为“代理器”。
Reflect对象与Proxy对象一样,也是 ES6 为了操作对象而提供的新 API

1
2
3
4
// 创建一个Proxy
new Proxy(obj, {});
// Reflect 获取对象属性
Reflect.get(obj, 'time');

Proxy 可以创建一个对象的代理 通过这个代理可以对源数据的更改进行权限管理

创建一个代理对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
{
let obj = {
time: '2017-08-12',
name: 'net',
_r: 123
};
// target 指的就是 obj 对象
// key 指的就是键名
// value 指的就是键值
let monitor = new Proxy(obj, {
// 拦截对象属性的读取
get(target, key) {
return target[key].replace('2017', '2018');
},
// 拦截对象设置属性的时候
set(target, key, value) {
if (key === 'name') {
return target[key] = value;
} else {
return target[key];
}
},
// 拦截 key in object 操作
has(target, key) {
if (key === 'name') {
return target[key];
} else {
return false;
}
},
// 拦截删除操作
deleteProperty(target, key) {
if (key.indexOf('_') > -1) {
delete target[key];
return true
} else {
return target[key]
}
},
// 拦截
// Object.keys,
// Object.getOwnPropertySymbols,
// Object.getOwnPropertyNames
ownKeys(target) {
return Object.keys(target).filter(item => item != 'time')
}
});
console.log('get', monitor.time); // 2018-08-12
monitor.time = '2018'; // 关掉 get
monitor.name = 'newname';
console.log('set', monitor.time, monitor.name);
// 2017-08-12 newname
console.log('has', 'name' in monitor, 'time' in monitor)
// true false
delete monitor.time;
console.log('deleteProperty', monitor); // 没有删除任何
delete monitor._r;
console.log('deleteProperty', monitor) // 删除了 _r 属性
console.log('ownKeys', Object.keys(monitor)) // 没有返回time属性
}

Reflect 用法跟 Proxy 一样

1
2
3
4
5
6
7
8
9
10
11
12
13
{
let obj = {
time: '2017-08-12',
name: 'net',
_r: 123
};
// 获取属性
Reflect.get(obj, 'time'); // 读取
Reflect.set(obj, 'name', 'newname'); // 设置
Reflect.has(obj, 'name'); // 判断
// ......
}

使用场景 数据类型的校验

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
{
function validator(target, validator) {
return new Proxy(target, {
_validator: validator,
set(target, key, value, proxy) {
if (target.hasOwnProperty(key)) {
let va = this._validator[key];
if (!!va(value)) {
return Reflect.set(target, key, value, proxy);
} else {
throw Error(`不能设置${key}${value}`);
}
} else {
throw Error(`${key}不存在`);
}
}
})
}
const personValidators = {
name(val) {
return typeof val === 'string';
// 这里返回的是 true or false
},
// name: function() {}
age(val) {
return typeof val === 'number' && val >= 18;
// 这里返回的是 true or false
}
// age: function(){}
}
class Person {
constructor(name, age) {
this.name = name;
this.age = age;
return validator(this, personValidators)
}
}
const person = new Person('lilei', 30);
person.name = 48; // 抛出错误
console.info(person);
person.name = 'new name'; // 设置正确
console.info(person);
}