Proxy 对象用于定义基本操作的自定义行为(如属性查找,赋值,枚举,函数调用等)。
也可以用来预警,上报,扩展功能,统计,增强对象等等
proxy是设计模式的一种,叫做代理模式
语法:
new Proxy (target, handler)
target 用Proxy
包装的目标对象(可以是任何类型的对象,包括原生数组,函数,甚至另一个代理)。
handler 一个对象,其属性是当执行一个操作时定义代理的行为的函数
let obj = new Proxy (被代理的对象,对被代理的对象做什么操作)
handler对象中存储了一些要对被代理对象所要进行的操作:
下面列举几个:
hander : {
set(){}, //设置的时候要做的操作
get(){}, //获取的时候要做操作
deleteProperty(){}, //删除的时候要做的操作
has(){}, //判断有没有某种属性的时候会调用
apply(){} //调用函数处理
....
}
上述函数和其他的一些handler函数都可以在下面的网址访问到:
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Proxy/handler
现在实现一个功能,当你访问对象中的一个属性时,提示你访问到了这个属性
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title></title>
<link rel="stylesheet" href="">
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
</head>
<body>
</body>
<script>
let obj = {
name: 'ReSword',
age: 21
};
console.log(obj.name);
let newObj = new Proxy(obj, {
get (target, property) {
console.log(target, property);
console.log(`You have access to the ${property} attribute.`);
return target[property];//不要用 . 用 . 的话访问不到
}
});
console.log(newObj.name);
</script>
</script>
</script>
</html>
一般在做代理的时候,比如obj是不暴露在外面的
现在做一个功能,如果访问了对象没有的属性,就提示错误
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title></title>
<link rel="stylesheet" href="">
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
</head>
<body>
</body>
<script>
let obj = {
name: 'ReSword',
age: 21
};
let newObj = new Proxy(obj, {
get (target, property) {
if (property in target) {
return target[property];
} else {
throw new ReferenceError(`${property} is not on this object`);
}
}
});
console.log(newObj.name);
console.log(newObj.age);
console.log(newObj.grade);
</script>
</html>
也可以这样写:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title></title>
<link rel="stylesheet" href="">
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
</head>
<body>
</body>
<script>
let obj = {
name: 'ReSword',
age: 21
};
let newObj = new Proxy(obj, {
get (target, property) {
if (property in target) {
return target[property];
} else {
// throw new ReferenceError(`${property} is not on this object`);
console.warn(`${property} is not on this object`)
return '^_^';
}
}
});
console.log(newObj.name);
console.log(newObj.age);
console.log(newObj.grade);
</script>
</html>
创建元素节点:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title></title>
<link rel="stylesheet" href="">
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
</head>
<body>
</body>
<script>
const DOM = new Proxy({}, {
get (target, property) {
return function (attr = {}, ...children) {
const el = document.createElement(property);
//添加属性
for (let key of Object.keys(attr)) {
el.setAttribute(key, attr[key]);
}
//添加子元素
for (let child of children) {
if (typeof(child) == 'string') {
child = document.createTextNode(child);
}
el.appendChild(child);
}
return el;
}
}
});
let div = DOM.div({id: 'div1'}, 'This is a div', 'This is a tip',
DOM.a({id: 'a1', href: 'http://erqingerhan.cn'}, 'This is a A')
);
document.body.appendChild(div);
</script>
</html>
Reflect
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title></title>
<link rel="stylesheet" href="">
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
</head>
<body>
</body>
<script>
function sum (a, b) {
return a + b;
}
let newSum = new Proxy(sum, {
apply (target, context, argus) {
return Reflect.apply(...arguments)**2;
}
})
console.log(newSum(2, 3));
</script>
</html>
Reflect.apply(调用的函数,this指向,参数数组)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title></title>
<link rel="stylesheet" href="">
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
</head>
<body>
</body>
<script>
function sum (a, b) {
return a + b;
}
let newSum = new Proxy(sum, {
apply (target, context, argus) {
console.log(target);
console.log(context);
console.log(argus);
console.log(arguments);
return Reflect.apply(...arguments)**2;
}
})
console.log(newSum(2, 3));
console.log(Reflect.apply(sum, undefined, [2, 3]));
</script>
</html>