Proxy

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

随着Vue2.x对Vue3.0的迁移,Vue的开发模式也有着巨大的变化,其重中之重就是数据劫持的方式发生了变化,由原先的Object.defineProperty变成了ES6中的Proxy。本文主要对Proxy进行一个简单的描述


提示:以下是本篇文章正文内容,下面案例可供参考,如有错误请指正。

一、Proxy是什么?

Proxy本质是一个构造函数,用于创建一个对象的代理,从而实现对被代理对象操作的的拦截和自定义(如属性查找,赋值,枚举,函数调用等)。相对于Object.defineProperty虽功能相似却有着本质的区别,Object.defineProperty从其本质上来说更像是官方向开发者开放的对于对象本身的一种扩展操作。

二、语法

const proxy = new Proxy(target, handler)

1.参数

  • target:要使用 Proxy 包装的目标对象(可以是任何类型的对象,包括原生数组,函数,甚至另一个代理)。
  • handler:一个通常以函数作为属性的对象,各属性中的函数分别定义了在执行各种操作时被代理对象的行为(可以将其理解为一个容器,容器中包含着一些列可以操作对象的方法)。

2.用法

let target = {
  a: 1,
  b: 2
}
let proxy = new Proxy(target, {
  get(target, prop) {
    console.log('this is property value is ' + target[prop]); // this is property value 1
    return target[prop]
  },
  set(target, prop, value) {
    console.log('this property value has been changed'); // this property value has been changed
    target[prop] = value
  },
})
proxy.a = 3
console.log(proxy.a); // 3
console.log(target.a) // 3

以上是一个非常简单的小例子,我们通过proxy代理的形式在不操作原对象的前提下实现了对对象的操作。
那Proxy能否对数组进行代理呢?
在Vue2.x中因为Object.defineProperty是无法对数组进行劫持的,所Vue在2.x时期使用了函数劫持的方式,重写了数组的方法,Vue将data中的数组进行了原型链重写,指向了自己定义的数组原型方法。这样当调用数组api时,可以通知依赖更新。如果数组中包含着引用类型,会对数组中的引用类型再次递归遍历进行监控。这样就实现了监测数组变化。
在Vue3.0中是否也进行了同样的操作呢?
让我们试验一下:

let arr = [1, 2]
let proxy = new Proxy(arr, {
  get(target, prop) {
    return target[prop]
  },
  set(target, prop, value) {
    target[prop] = value
  }
})
proxy[0] = 3
console.log(proxy);

打印的内容:
在这里插入图片描述
如上图所示,数据已经被更改,于是我们知道Proxy不仅仅可以代理对象,同时也可以代理数组。

那既然可以代理数组,那会不会也可以代理Function呢?
继续尝试Proxy是否可以代理Function:

let fn = function () {
  console.log('i am a function');
}
fn.a = 1

let proxyFn = new Proxy(fn, {
  get(target, prop) {
    return 'this is property value is ' + target[prop]
  }
})
console.log(proxyFn.a) // this is property value is 1

经测试proxy同样可以代理Function。

3.总结

通过以上检验可以得出Proxy可以代理js中引用类型的数据。

另外handler中除了get方法和set方法还包含很多种方法,详情可以查看MDN上的文档,此处就不一一列举了。

handler 对象的方法

Logo

前往低代码交流专区

更多推荐