Proxy 对象用于创建一个对象的代理,从而实现基本操作的拦截和自定义(如属性查找、赋值、枚举、函数调用等)。
语法: new proxy(target, handler)
target是被代理的对象,
handler是一个对象, 属性是函数, 用来处理对代理行为, 比如get set construct has apply等属性, 分别对应代理对象的取值, 设置值, new 和 in 和函 数调用的操作
1, 代理(拦截)set 操作: 每次对proxObject进行赋值操作 可以进行拦截
例子: 改变一个对象的属性, 就会引起页面的重新渲染;
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 6 <meta http-equiv="X-UA-Compatible" content="ie=edge"> 7 <title>Document</title> 8 </head> 9 <body> 10 11 <div id="container"></div> 12 <script> 13 var obj = {//这是一个被代理对象 14 a: 1, 15 b: 2 16 } 17 var div = document.getElementById("container"); 18 var proxy = new Proxy(obj, { //set get时候, 可以对被代理对象操作 19 set (obj, prop, value) { 20 console.log(obj, prop, value); 21 Reflect.set(obj,prop,value); 22 render(); 23 24 }, 25 get (obj, prop){ 26 console.log(obj,prop); 27 return Reflect.get(obj, prop) 28 } 29 }) 30 function render(){ //渲染函数 31 let html = ''; 32 let keys = Object.keys(proxy); 33 for(let item of keys){ 34 html += ` 35 <p> 36 ${item}:${proxy[item]} 37 </p> 38 ` } 39 div.innerHTML = html; 40 } 41 render() 42 </script> 43 </body> 44 </html>
2. 对构造函数中this.xx = xx这种方式的简化: 拦截new
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> </head> <body> <script> class Anamal { constructor() { } } function constructProxy(target, ...props) { var proxy = new Proxy(target, { construct(target, arguments) { // var obj = new target(); var obj = Reflect.construct(target, arguments) //这里用construct函数,非常清晰的是对new的拦截 props.forEach((element, index) => { // obj[element] = arguments[index] Reflect.set(obj, element, arguments[index]) }); return obj } }) return proxy; } var proxy_Anamal = constructProxy(Anamal, "name", "age"); var dog = new proxy_Anamal("dog", 18) console.log(dog); </script> </body> </html>
3 函数调用的拦截: apply
<html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> </head> <body> <script> function add(a, b) { return a + b; } function check(target, ...types) { var proxy = new Proxy(add, { apply: function (target, thisArg, argumentsList) { //apply对函数调用的检测,
argumentsList.forEach((ele, index) => { if (typeof ele != types[index]) { throw new TypeError(`第${index}个参数的类型不是${types[index]}`) } }) //return target(...argumentsList)
return Reflect.apply(target,thisArg,argumentsList)
} }) return proxy; } var prox_add = check(add, "number", "number"); var result = prox_add(3, "7") console.log(result); </script> </body> </html>