这篇文章我们看一些例子,看看怎么使用代理。
1)有意思的rest访问方式
let service = createWebService('http://example.com/data');
service.employees.then(json => {
let employees = JSON.parse(json);
console.log(employees);
});
function createWebService(baseUrl) {
return new Proxy({}, {
get(target, propKey, receiver) {
return httpGet(baseUrl+'/'+propKey);
}
});
}
function httpGet(url) {//简单模拟了http的过程
return new Promise((resolve, reject) => {
setTimeout(function(){
resolve('{"name":"john","age":41,"sex":"male"}');
},1000)
});
}
利用上面这种形式,我们可以更好的模块化以及模型化rest方法的调用。
2)属性检查器
let PropertyChecker = new Proxy({}, {
get(target, propKey, receiver) {
if (!(propKey in target)) {
throw new ReferenceError('Unknown property: '+propKey);
}
return Reflect.get(target, propKey, receiver);
}
});
let obj = { __proto__: PropertyChecker, foo: 123 };
obj.foo;
obj.fo;//ReferenceError: Unknown property: fo
obj.toString();
还可以定义类来继承PropertyChecker:
function PropertyChecker() { }
PropertyChecker.prototype = new Proxy({}, {
get(target, propKey, receiver) {
if (!(propKey in target)) {
throw new ReferenceError('Unknown property: '+propKey);
}
return Reflect.get(target, propKey, receiver);
}
});
class Point extends PropertyChecker {
constructor(x, y) {
this.x = x;
this.y = y;
}
}
let p = new Point(5, 7);
console.log(p.x); // 5
console.log(p.z); // ReferenceError
3)数组下标的负数索引访问
function createArray(...elements) {
let handler = {
get(target, propKey, receiver) {
let index = Number(propKey);
if (index < 0) {
propKey = String(target.length + index);
}
return target[propKey];
}
};
let target = [];
target.push(...elements);
return new Proxy(target, handler);
}
let arr = createArray('a', 'b', 'c');
console.log(arr[-1]); // c
4)跟踪对象属性访问
function tracePropAccess(obj, propKeys) {
let propKeySet = new Set(propKeys);
return new Proxy(obj, {
get(target, propKey, receiver) {
if (propKeySet.has(propKey)) {
console.log('GET '+propKey);
}
return target[propKey];
},
set(target, propKey, value, receiver) {
if (propKeySet.has(propKey)) {
console.log('SET '+propKey+'='+value);
}
target[propKey] = value;
}
});
}
class Point {
constructor(x, y) {
this.x = x;
this.y = y;
}
toString() {
return 'Point('+this.x+','+this.y+')';
}
}
// Trace accesses to properties `x` and `y`
let p = new Point(5, 7);
p = tracePropAccess(p, ['x', 'y']);
p.x;
p.x = 21;
p.toString();
*以上全部代码在Firefox 44下通过测试