阅读 697

Proxy知识梳理(proxy.newproxyinstance原理)

Proxy 意思为代理,即在访问对象之前建立一道拦截,任何访问该对象的操作之前都会通过这道拦截

Proxy可以拦截什么

  • getPrototypeOf()

  • setPrototypeOf()

  • isExtensible()

  • preventExtensions()

  • getOwnPropertyDescriptor()

  • defineProperty()

  • has()

  • get()

  • set()

  • deleteProperty()

  • ownKeys()

  • apply()

  • construct()

实例

Proxy 语法

let proxy = new Proxy(target, handler); 复制代码

这就是Proxy的使用方法,所有的用法都是上面的方法,不同的是handler里面拦截的设置

new Proxy()表示生成一个Proxy实例

target表示要拦截的目标对象

handler是一个对象,用来定制拦截方法

想要handler里的拦截方法生效,后续所有操作必须使用Proxy的实例

get

get方法在日常开发中应该是使用最多的方法了,先看一下在不使用Proxy时候的场景

let user = {   name: "张三", }; console.log(user.name); //张三 console.log(user.age); //undefined 复制代码

运行代码

上面代码中,使用let定义了一个对象,并且有一个name属性

然后分别打印出nameage属性,结果很明显,age属性未定义会输出undefined

但是在实际项目中我们是不希望返回undefined这种值给页面的,下面我们就看一下怎么使用Proxy解决这个问题

let handler = {   //定义了get方法的拦截器   get: function (target, key) {     //target:要拦截的对象     //key: 修改的属性       if(target.hasOwnProperty(key)){           if(key=='name'){            return "法外狂徒-张三"          }       }        return "18"   } }; let obj = {   name: "张三" }; let user = new Proxy(obj, handler); //注意,这里的user不是上个示例的user对象了,而是Proxy的实例 console.log(user.name); //法外狂徒-张三 console.log(user.age); //18 复制代码

运行代码

使用了Proxy之后,发现和之前什么都不一样了,这是因为我们设置了get方法的拦截,当获取name属性的时候,我们返回一个固定的值,否则就返回年龄18。

这里是不太严谨的,实际项目中不可能只有两个字段的,这里只是为了演示

想要handler里的拦截方法生效,后续所有操作必须使用Proxy的实例

这个时候可以验证一下这句话,我们不使用Proxy实例,看看会怎么样

运行代码

set

在实际项目中,我们会经常进行修改某个对象的属性,有时候在一些特殊的场景下需要对对象修改的新属性进行判断,看是否符合当前的业务场景。

let user = new Proxy( {   age: 18 }, {   set: function (target, key, value) {     if (value > 140) {       throw "你要成仙了!";     }     target[key]=value   } } ); user.age = 20; console.log(user.age)//20 user.age=200 //Uncaught 你要成仙了!  复制代码

运行代码

当我们修改一个人的年龄大于140,就会触发异常

construct

construct方法用于拦截new操作符,为了使new操作符在生成的Proxy对象上生效,用于初始化代理的目标对象自身必须具有Construct内部方法

示例

let proxy = new Proxy(1, {  construct(target, args) {    console.log(target);    return new target(...args);  } }); //Uncaught TypeError: Cannot create proxy with a non-object as target or handler  复制代码

运行代码

 let proxy = new Proxy(function () {}, {  construct(target, args) {    console.log(args);    return 1;  } }); let obj = new proxy(); //Uncaught TypeError: 'construct' on proxy: trap returned non-object ('1')  复制代码

运行代码

上面是两个错误的示例,下面写一个正确的写法

var p = new Proxy(function() {}, {  construct: function(target, argumentsList, newTarget) {    console.log('called: ' + argumentsList.join(', '));    return { value: argumentsList[0] * 10 };  } }); console.log(new p(1).value); // "called: 1"                             // 10 复制代码

运行代码

通过以上代码得出结论

  • 要代理的对象必须具有Construct方法

  • 必须返回一个对象

其他


作者:xx小台灯
链接:https://juejin.cn/post/7011400461110476837

伪原创工具 SEO网站优化  https://www.237it.com/ 


文章分类
代码人生
文章标签
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐