JS Proxy(代理)
前言
Proxy 也就是代理,可以帮助我们完成很多事情,例如对数据的处理,对构造函数的处理,对数据的验证,说白了,就是在我们访问对象前添加了一层拦截,可以过滤很多操作,而这些过滤,由你来定义。
想了解更多请参考 官方文档
语法
- let p = new Proxy(target, handler);
参数
target
:需要使用Proxy
包装的目标对象(可以是任何类型的对象,包括原生数组,函数,甚至另一个代理)。handler
: 一个对象,其属性是当执行一个操作时定义代理的行为的函数(可以理解为某种触发器)。具体的handler
相关函数请查阅官网
下面是使用示例,一个简单的代理:
- let test = {
- name: "小红"
- };
- test = new Proxy(test, {
- get(target, key) {
- console.log('获取了getter属性');
- return target[key];
- }
- });
- console.log(test.name);

上方的案例,我们首先创建了一个test对象,里面有name属性,然后我们使用Proxy
将其包装起来,再返回给test,此时的test已经成为了一个Proxy
实例,我们对其的操作,都会被Proxy
拦截。
Proxy
有两个参数,第一个是target
,也就是我们传入的*test对象,另一个则是handler
,也就是我们传入的第二个参数,一个匿名对象。在handler
中定义了一个名叫get
的函数,当我们获取 test的属性时,则会触发此函数。
咱们再来试试使用set
来拦截一些操作,并将get
返回值更改
- let xiaohong = {
- name: "小红",
- age: 15
- };
- xiaohong = new Proxy(xiaohong, {
- get(target, key) {
- let result = target[key];
- //如果是获取 年龄 属性,则添加 岁字
- if (key === "age") result += "岁";
- return result;
- },
- set(target, key, value) {
- if (key === "age" && typeof value !== "number") {
- throw Error("age字段必须为Number类型");
- }
- return Reflect.set(target, key, value);
- }
- });
- console.log(`我叫${xiaohong.name} 我今年${xiaohong.age}了`);
- xiaohong.age = "aa";

上方案例中定义了 xiaohong 对象,其中有 age 和 name 两个字段,我们在Proxy
中的 get 拦截函数中添加了一个判断,如果是取 age 属性的值,则在后面添加 岁。在 set 拦截函数中判断了如果是更改 age 属性时,类型不是 Number
则抛出错误。最后,正确的输出了我们想要的结果!
关于return Reflect.set(target, key, value);
这句代码,可以用其他方式替换,例如 :
- let xiaohong = {
- name: "小红",
- age: 15
- };
- xiaohong = new Proxy(xiaohong, {
- get(target, key) {
- let result = target[key];
- //如果是获取 年龄 属性,则添加 岁字
- if (key === "age") result += "岁";
- return result;
- },
- set(target, key, value) {
- if (key === "age" && typeof value !== "number") {
- throw Error("age字段必须为Number类型");
- }
- target[key] = value;
- // return Reflect.set(target, key, value);
- }
- });
- console.log(`我叫${xiaohong.name} 我今年${xiaohong.age}了`);
- xiaohong.age = 12;

此时会抛出一个错误,因为set
函数必须返回一个boolean
值,只有返回值为true
时才表示修改成功,我们没有手动return
,函数会自动返回undefined
,undefined != true
,所以报错是正常的,只需要手动在最后添加一句 return true
即可!
但是,既然JS为我们提供了 Reflect
,那我们肯定是使用它啦,毕竟它和Proxy
本来就是一起玩的,Proxy
有的函数它都有!具体的参考 官方链接
这只是最基础的应用,其他的大家可以自行摸索,都是一样的用法!
打字不易,点赞的你最靓了...
JS Proxy(代理)的更多相关文章
- python + seleinum +phantomjs 设置headers和proxy代理
python + seleinum +phantomjs 设置headers和proxy代理 最近因为工作需要使用selenium+phantomjs无头浏览器,其中遇到了一些坑,记录一下,尤 ...
- C# 使用 Proxy 代理请求资源
C# 使用 Proxy 请求资源,基于 HttpWebRequest 类 前言 这是上周在开发 C# 中使用 Proxy 代理时开发的一些思考和实践.主要需求是这样的,用户可以配置每次请求是否需要代理 ...
- java中Proxy(代理与动态代理)
转自: https://blog.csdn.net/pangqiandou/article/details/52964066 一.代理的概念 动态代理技术是整个java技术中最重要的一个技术,它是学习 ...
- C++设计模式-Proxy代理模式
Proxy代理模式 作用:为其他对象提供一种代理以控制对这个对象的访问. 代理的种类: 如果按照使用目的来划分,代理有以下几种: 远程(Remote)代理:为一个位于不同的地址空间的对象提供一个局域代 ...
- ES6新特性:Proxy代理器
ES6新特性:Proxy: 要使用的话, 直接在浏览器中执行即可, node和babel目前还没有Proxy的polyfill;,要使用的话,直接在浏览器中运行就好了, 浏览器的兼容性为:chrome ...
- Apache开启Proxy代理,实现域名端口转发
今天帮客户迁移网站,客户一个是ASPX的一个是PHP的网站,这时候有2个域名,可是php网站是Apache下的伪静态,必须要用到Apache,但是ASPX网站还必要到IIS+Mssql 然后到了这个时 ...
- php设计模式之Proxy(代理模式)和Facade(外观)设计模式
Proxy(代理模式)和Facade(外观)设计模式它们均为更复杂的功能提供抽象化的概念,但这两种实现抽象化的过程大不相同 Proxy案例中,所有的方法和成员变量都来自于目标对象,必要时,该代理能够对 ...
- Proxy 代理模式
简介 代理模式是用一个简单的对象来代替一个复杂的或者创建耗时的对象. java.lang.reflect.Proxy RMI 代理模式是对象的结构模式.代理模式给某一个对象提供一个代理对象,并由代理对 ...
- 第四章:使用Proxy代理让客户端服务端分工合作。
<基于1.8 Forge的Minecraft mod制作经验分享> 别被那个Proxy代理吓到,很简单的. 我们先讨论为什么要用Proxy代理: 像打开新的UI这种操作,比如打开一个背包, ...
随机推荐
- LNMP-Nginx负载均衡
Nginx负载均衡介绍 Nginx提供负载均衡的模块upstream,这个模块是默认的,不需要重新编译模块.通常情况下,负载均衡一般用于后端两台机器同时提供服务供用户访问,但是用户经常访问的其中一台服 ...
- 【MyBatis】动态 SQL
[MyBatis]动态 SQL 转载: 目录 ========================================== 1.if 2.choose when otherwise 3.tri ...
- 201871010119-帖佼佼《面向对象程序设计(java)》第四周学习总结
项目 内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh/ 这个作业的要求在哪里 https://www.cnblogs.com/nwnu-daizh ...
- Docker swarm实战总结
一.简介 Swarm 是 Docker 官方提供的一款集群管理工具,其主要作用是把若干台 Docker 主机抽象为一个整体,并且通过一个入口统一管理这些 Docker 主机上的各种 Docker 资源 ...
- 前后端分离crud(跨域问题)讲解
1 前后端分离 1.1 后端 ssm+maven 多模块 swagger 文档描述(代码拷贝过来,就可以生成了,https://www.cnblogs.com/wings-xh/p/11991511. ...
- SpringCloud-服务注册与实现-Eureka创建服务注册中心(附源码下载)
场景 SpringCloud学习之运行第一个Eureka程序: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/90611451 S ...
- git版本控制入门--码云
1.下载git:https://git-scm.com/download 2.安装过程一直点下一步即可. 3.进入刚创建的文件夹 4.在此时登录码云,创建项目.项目名称最好与文件夹名称 ...
- 记录MyBatis text类型 查询 更新 数据是null
数据库表里面存在text或者blob字段.逆向工程自动生成的MyBatis的xml中会多出几个以withBlobs结尾的方法和resultMap 此时查询数据或者更新数据的使用仍然使用selectBy ...
- web中状态码301和302的区别
web中状态码301和302的区别 总的区别就是:302重定向只是暂时的重定向,搜索引擎会抓取新的内容而保留旧的地址,因为服务器返回302,所以,搜索搜索引擎认为新的网址是暂时的.而301重定向是永久 ...
- HTML DOM属性
innerHTML属性 获取元素内容的最简单方法是使用innerHTML属性 innerHTML属性对于获取或替换HTML元素的内容很有用 innerHTML属性可用于获取或改变任意HTML元素,包括 ...