proxy

用于代理对象、数组、函数。可以对其做一些特殊处理,把修改完的数据返回出去、

  1. // 代理 对象
  2. let obj = {a :1}
  3. let nObj = new Proxy(obj,{
  4. get(target,property){
  5. return target[property]
  6. },
  7. set(target,property,value){
  8. return target[property] = value
  9. }
  10. })
  11. // 代理 数组
  12. let arr = ['a','b','c']
  13. let nArr = new Proxy(arr,{
  14. get(target,property){
  15. return target[property]
  16. },
  17. set(target,property,value){
  18. return target[property] = value
  19. }
  20. })
  21. console.log(nArr)
  22. nArr[0] = 'd'
  23. // 转为数组 => 不知道这种解题思路是否正确
  24. let newArr = [...new Set(nArr.values())]
  25. console.log(newArr)

常用方法

方法 描述
handler.apply() 拦截 Proxy 实例作为函数调用的操作
handler.construct() 拦截 Proxy 实例作为函数调用的操作
handler.defineProperty() 拦截 Object.defineProperty() 的操作
handler.deleteProperty() 拦截 Proxy 实例删除属性操作
handler.get() 拦截 读取属性的操作
handler.set() 拦截 属性赋值的操作
handler.getOwnPropertyDescriptor() 拦截 Object.getOwnPropertyDescriptor() 的操作
handler.getPrototypeOf() 拦截 获取原型对象的操作
handler.has() 拦截 属性检索操作
handler.isExtensible() 拦截 Object.isExtensible()操作
handler.ownKeys() 拦截 Object.getOwnPropertyDescriptor() 的操作
handler.preventExtension() 拦截 Object().preventExtension() 操作
handler.setPrototypeOf() 拦截Object.setPrototypeOf()操作
Proxy.revocable() 创建一个可取消的 Proxy 实例

get

获取代理的值

  1. let obj = {
  2. name: '前端伪大叔'
  3. }
  4. // 第一个参数是需要代理的对象
  5. // 第二个参数代理的方法
  6. let newObj = new Proxy(obj,{
  7. // 1、代理的对象 2、代理的对象的key
  8. get(target,property){
  9. if(property in target){
  10. return target[property]
  11. }else{
  12. console.warn(`${property}不存在`)
  13. }
  14. }
  15. })
  16. console.log(newObj.name); // 前端伪大叔
  17. console.log(newObj.Proxy);// Proxy不存在

set

修改代理的value值,可以在返回的地方返回boolean值。如果没有修改返回false

  1. let newObj = new Proxy(obj, {
  2. // 1、代理的对象 2、key值 3、修改的key
  3. set(target, property, value) {
  4. // 判断对象的value是否被修改
  5. if (target[property] === value) {
  6. return target[property]
  7. } else {
  8. return target[property] = value
  9. }
  10. }
  11. })
  12. console.log(newObj.name);
  13. newObj.name = '1'
  14. console.log(newObj.name);

has

针对 in 操作符做的代理,

  1. let obj = {
  2. name: '前端伪大叔',
  3. age: 19
  4. }
  5. let newObj = new Proxy(obj, {
  6. // 1、代理的对象 2、需要劫持的属性
  7. has(target, prop) {
  8. // 只有key是name的时候才返回true
  9. if (prop === 'name') {
  10. return true
  11. } else {
  12. return false
  13. }
  14. }
  15. })
  16. console.log('name' in newObj); // true
  17. console.log('age' in newObj); // false

apply

拦截函数的调用

  1. function fun (a,b) { return a + b}
  2. let funs = new Proxy(fun,{
  3. // 1、函数本身 2、被调用的上下文对象 3、传入的参数(array格式)
  4. apply(target,thisArg,argumentsList){
  5. return argumentsList[0] + argumentsList[1] * 2
  6. }
  7. })
  8. console.log(funs(1,2));

deleteProperty

拦截删除的对象

  1. let newObj = new Proxy(obj, {
  2. // 1、传入对象 2、key
  3. deleteProperty(target, property) {
  4. // 只能删除对象 key值为a的
  5. if(property === 'a'){
  6. delete target[property]
  7. }else{
  8. alert('只能删除a')
  9. }
  10. }
  11. })
  12. delete newObj.a;
  13. delete newObj.b;
  14. console.log(newObj);