js Proxy的原理详解

 更新时间:2021年05月25日 10:33:52   作者:shiramashiro  
Proxy用于修改某些操作的默认行为,在目标对象前架设一个“拦截”层,外界对该对象的访问都必须先通过这一层拦截,因此提供了一种机制可以对外界的访问进行过滤和改写。本文就讲讲Proxy的使用

什么是代理模式

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

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

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

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

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

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

什么是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分别接收到的信息如图所示

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

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

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

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

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

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的三个参数分别接收到的信息如下图所示。

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

很明显,会抛出异常。

总结

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

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

以上就是js Proxy的原理详解的详细内容,更多关于js Proxy的资料请关注脚本之家其它相关文章!

相关文章

  • JavaScript获取多个数组的交集简单实例

    JavaScript获取多个数组的交集简单实例

    这篇文章介绍了JavaScript获取多个数组的交集简单实例,有需要的朋友可以参考一下
    2013-11-11
  • 实例详解带参数的 npm script

    实例详解带参数的 npm script

    本文通过实例代码给大家介绍了带参数的 npm script,非常不错,具有一定的参考借鉴价值,需要的朋友可以参考下
    2019-05-05
  • JavaScript模块化原理深入分析

    JavaScript模块化原理深入分析

    JavaScript中的模块化是指将每个js文件会被认为单独一个的模块。模块之间是互相不可见的。如果一个模块需要使用另一个模块,那么需要通过指定语法来引入要使用的模块,而且只能使用引入模块所暴露的内容
    2022-11-11
  • typescript中type和interface的区别有哪些

    typescript中type和interface的区别有哪些

    大家使用typescript总会使用到interface和type,所以下面这篇文章主要给大家介绍了关于typescript中type和interface区别的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2022-02-02
  • 原生js做的手风琴效果的导航菜单

    原生js做的手风琴效果的导航菜单

    手风琴效果的导航想必大家都有见到过吧,实现的方法也有很多,在本文为大家介绍下使用原生js简单实现下,感兴趣的朋友不要错过
    2013-11-11
  • js保存当前路径(cookies记录)

    js保存当前路径(cookies记录)

    曾经做了一个取消订单的功能。这个功能在个人中心里面有,在订单的详细页面也有。按照正常的思路,这两块都可以提交到相同的action去处理,但是返回的页面是不一样的,都是返回到当前页面就可以了。
    2010-12-12
  • 简单通过settimeout看javascript的运行机制

    简单通过settimeout看javascript的运行机制

    这篇文章主要给大家介绍了关于如何通过settimeout看javascript的运行机制的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用javascript具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-05-05
  • nodejs创建web服务器之hello world程序

    nodejs创建web服务器之hello world程序

    本文给大家分享nodejs创建web服务器之hello world程序,node真的很好用,不仅用v8引擎来解析了javascript外,还提供了高度优化的应用库,真的很好,有需要的朋友一起来学习吧
    2015-08-08
  • echart简介_动力节点Java学院整理

    echart简介_动力节点Java学院整理

    这篇文章主要介绍了echart简介,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-08-08
  • JavaScript模拟实现网易云轮播效果

    JavaScript模拟实现网易云轮播效果

    这篇文章主要介绍了如何利用JavaScript模仿网易云轮播效果的实现,文中的示例代码讲解详细,对我们学习有一定帮助,需要的可以参考一下
    2022-04-04

最新评论