js Proxy的原理详解


Posted in Javascript onMay 25, 2021

什么是代理模式

引入一个现实生活中的案例

我们作为用户需要去如何评估一个房子的好坏、如何办理住房手续等一些列繁琐的事物吗?显然,用户肯定不愿意这样做。用户最关心的是结果,用户对房子提出需求以及提供对等价值的金钱就可以获得满意的房子,这就是结果。

那么谁为用户去解决一系列繁琐的买房过程呢?当然就是“房屋中介”了!房屋中介的作用就是在房地产开发经营与消费的供求市场中,为交易物体提供评估、交易、代理、咨询等服务及善后服务的机构。

结合案例理解代理模式的定义

在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。

代理模式就是为其他用户提供一种代理,用户不用知道买房的具体过程,而用户应该关心的是如何获得满意的结果,代理所需要做的事情就是完成这一买房的过程。

什么是Proxy

Proxy支持的拦截操作有许多中,目前只针对get(target, propKey, receiver)和set(target, propKey, value, receiver)来讲。

  • get方法:拦截对象属性的读取;
  • set方法:拦截对象属性的设置。

get(target, propKey, receiver)

定义一个Person对象,它将被Proxy代理,外界通Proxy实例对象来访问Person对象。

var person = {
    name: "kongsam",
    age: 21,
    hobbies: [
        "看动漫",
        "骑行",
        "玩游戏"
    ]
}

实例化一个Proxy对象,用于拦截外界对Person对象的操作。

var proxy = new Proxy(person, {
    get: function (target, property) {
          // 打印target和property,查看里面到底是什么。
          console.log("target = ", target);
          console.log("property = ", property);
          // 判断外界访问的对象属性是否存在于目标对象中。
          if (property in target) {
                return target[property];
          } else {
                // 如果外界访问的对象属性不存在与目标对象中,抛出异常。
                throw new ReferenceError('Property "' + property + '" 不存在。');
          }
    },
});

当进行proxy.name操作时,由于Person对象已经被Proxy代理了,所以每当我通过该Proxy实例对象访问Person中存在的属性时,都会调用get方法,get方法是拦截对象属性的读取的。

get: function (target, property) 中的两个参数target和property分别接收到的信息如图所示

js Proxy的原理详解

通过该代理对象访问Person对象中存在的属性不会出现任何异常,如果访问不存在的属性会发生什么?

js Proxy的原理详解

是什么,以至于访问不存在的属性时,它会抛出异常呢?

这是因为外界对Person对象的访问都必须先通过Proxy设置的拦截层,而拦截层提供了一种机制可以对外界的访问进行过滤和改写。

// 判断外界访问的对象属性是否存在于目标对象中。
if (property in target) {
    return target[property];
} else {
    // 如果外界访问的对象属性不存在与目标对象中,抛出异常。
    throw new ReferenceError('Property "' + property + '" 不存在。');
}

if语句就是拦截层的具体操作,即对外界的访问进行过滤和改写。如果没有,访问不存在的属性就会返回undefined。

js Proxy的原理详解

set(target, propKey, value, receiver)

依旧是Person对象,这时我有个新需求,即修改age属性时,值不能超过150且是整数。

新增Proxy对象中的set方法。

var proxy = new Proxy(person, {
    set: function (target, property, value) {
          // 打印target、property和value,查看里面到底是什么。
          console.log("target = ", target);
          console.log("property = ", property);
          console.log("value = ", value);
          if (property === "age") {
                if (!Number.isInteger(value)) {
                  throw new TypeError("age的值不是整数!");
                }
                if (value > 150) {
                  throw new RangeError("age的值不能大于150!");
                }
          }
    },
});

当我执行proxy.age = 100时,set的三个参数分别接收到的信息如下图所示。

js Proxy的原理详解

set方法用于拦截某个属性的赋值操作,我如果对age的赋值操作不满足条件时,会发生什么?

js Proxy的原理详解

很明显,会抛出异常。

总结

Proxy就是拦截层,你给出被拦截的对象,外界访问这个对象必须先通过拦截层,即访问Proxy的实例对象。通过Proxy为外界访问进行过滤和改写,如赋值时需满足某些条件。

代理对象中还有许多的方法,如has、deleteProperty、ownKeys、getOwnPropertyDescriptor等,都是用于拦截不同的情况而出现的。

以上就是js Proxy的原理详解的详细内容,更多关于js Proxy的资料请关注三水点靠木其它相关文章!

Javascript 相关文章推荐
完美解决JS中汉字显示乱码问题(已解决)
Dec 27 Javascript
用Javascript评估用户输入密码的强度实现代码
Nov 30 Javascript
AngularJS入门教程之学习环境搭建
Dec 06 Javascript
基于JavaScript代码实现微信扫一扫下载APP
Dec 30 Javascript
学习javascript面向对象 掌握创建对象的9种方式
Jan 04 Javascript
JavaScript实现iframe自动高度调整和不同主域名跨域
Feb 27 Javascript
js中offset,client , scroll 三大元素知识点总结
Sep 11 Javascript
JavaScript的console命令使用实例
Dec 03 Javascript
vue实现图片懒加载的方法分析
Feb 05 Javascript
vue2.0 解决抽取公用js的问题
Jul 31 Javascript
keep-alive保持组件状态的方法
Dec 02 Javascript
JS+JQuery实现无缝连接轮播图
Dec 30 jQuery
解析原生JS getComputedStyle
80行代码写一个Webpack插件并发布到npm
Ajax请求超时与网络异常处理图文详解
May 23 #Javascript
vue-element-admin项目导入和导出的实现
May 21 #Vue.js
vue2实现provide inject传递响应式
May 21 #Vue.js
JS + HTML 罗盘式时钟的实现
JavaScript canvas实现流星特效
May 20 #Javascript
You might like
使用PHP开发留言板功能
2019/11/19 PHP
防止网站内容被拷贝的一些方法与优缺点好处与坏处分析
2007/11/30 Javascript
js 页面传参数时 参数值含特殊字符的问题
2009/12/13 Javascript
Jquery之Ajax运用 学习运用篇
2011/09/26 Javascript
innerHTML与jquery里的html()区别介绍
2012/10/12 Javascript
JS面向对象基础讲解(工厂模式、构造函数模式、原型模式、混合模式、动态原型模式)
2014/08/16 Javascript
Javascript中的getUTCDay()方法使用详解
2015/06/10 Javascript
node.js中格式化数字增加千位符的几种方法
2015/07/03 Javascript
JavaScript中数组的合并以及排序实现示例
2015/10/24 Javascript
漫谈JS引擎的运行机制 你应该知道什么
2016/06/15 Javascript
AngularJS基础 ng-repeat 指令简单示例
2016/08/03 Javascript
Node.js 中exports 和 module.exports 的区别
2017/03/14 Javascript
postman+json+springmvc测试批量添加实例
2018/03/31 Javascript
VUE 实现动态给对象增加属性,并触发视图更新操作示例
2019/11/29 Javascript
修改Vue打包后的默认文件名操作
2020/08/12 Javascript
在vue中实现清除echarts上次保留的数据(亲测有效)
2020/09/09 Javascript
[03:59]DOTA2英雄梦之声_第07期_水晶室女
2014/06/23 DOTA
Django中对数据查询结果进行排序的方法
2015/07/17 Python
Django模板变量如何传递给外部js调用的方法小结
2017/07/24 Python
python DataFrame 修改列的顺序实例
2018/04/10 Python
python 编码规范整理
2018/05/05 Python
在python中实现对list求和及求积
2018/11/14 Python
基于Python实现船舶的MMSI的获取(推荐)
2019/10/21 Python
python numpy 反转 reverse示例
2019/12/04 Python
python代码如何实现余弦相似性计算
2020/02/09 Python
如何安装并在pycharm使用selenium的方法
2020/04/30 Python
如何利用python读取micaps文件详解
2020/10/18 Python
SmartBuyGlasses荷兰:购买太阳镜和眼镜
2020/03/16 全球购物
护士自我鉴定范文
2013/10/06 职场文书
门诊挂号室室长岗位职责
2013/11/27 职场文书
运动会广播稿30字
2014/01/21 职场文书
领班岗位职责范文
2014/02/06 职场文书
计算机科学与技术专业求职信
2014/09/03 职场文书
2015年上半年信访工作总结
2015/03/30 职场文书
微软PC Health Check电脑健康状况检查应用下载(Win11配置检测工具)
2021/06/26 数码科技
python之PySide2安装使用及QT Designer UI设计案例教程
2021/07/26 Python