ES6语法Proxy的基本使用
最近接触Vue3越来越多,大家都知道Vue3中的ref是使用get和set拦截value实现的,所以用ref定义的数据需要用.value的方式来访问,但是reactive是使用proxy和reflect来实现的,就趁着这个时间把Proxy和Reflect 先看一看,本篇仅限于Proxy,Reflect会单独开一篇笔记。
基本概念
Proxy 对象用于创建一个对象的代理,从而实现基本操作的拦截和自定义
Proxy是一个可构造对象,通过new创建实例。
语法:
1 | const p = new Proxy(target, handler) |
参数:
target
要使用
Proxy包装的目标对象(可以是任何类型的对象,包括原生数组,函数,甚至另一个代理)。handler
一个通常以函数作为属性的对象,各属性中的函数分别定义了在执行各种操作时代理
p的行为。
Proxy的方法
除了直接 new Proxy 对象外,Proxy 构造函数上还有一个静态函数 revocable,可以构造一个能被销毁的代理对象。
与new Proxy创建的代理对象不同,revocable还会返回一个销毁函数:
1 | Proxy.revocable( target: Object, handlers: Object ) : Object |
销毁函数不需要任何参数,我们可以随时调用销毁函数将代理对象和目标对象的代理关系断开。断开代理后,再对代理对象执行任何操作都会抛出 TypeError 错误。
Proxy特点
- Proxy 在处理属性名的时候会把除 Symbol 类型外的所有属性名都转化成字符串,所以处理函数在判断属性名时需要尤其注意。
- 对代理对象的任何操作都会被拦截,一旦代理对象被创建就没有办法再修改它本身。
- Proxy 的代理是非常底层的,在没有主动暴露原始目标对象的情况下,没有任何办法越过代理对象访问目标对象
- Proxy 代理的目标只能是对象,不能是 JavaScript 中的原始类型
handler方法
handler 对象是一个容纳一批特定属性的占位符对象。它包含有 Proxy 的各个捕获器(trap)。
所有的捕捉器是可选的。如果没有定义某个捕捉器,那么就会保留源对象的默认行为。
- apply()
- construct()
- defineProperty ()
- deleteProperty ()
- get ()
- getOwnPropertyDescrip ()
- getPrototypeOf ()
- has ()
- isExtensible ()
- ownKeys ()
- preventExtensions ()
- set ()
- setPrototypeOf ()
handler的方法我们称之为陷阱。每个陷阱用于捕获一种行为。
defineProperty和deleteProperty
defineProperty用于拦截Object.defineProperty操作,返回一个布尔值,表示该操作是否成功。
deleteProperty用于拦截属性的delete操作,也是返回布尔值。
get
get用于拦截属性的读取操作,是很常用的属性。
1 | var p = new Proxy(target, { |
target : 目标对象。
property : 被获取的属性名。
receiver : Proxy 或者继承 Proxy 的对象
set
set方法拦截对属性值的操作
1 | const p = new Proxy(target, { |
应当返回一个布尔值。返回 true 代表属性设置成功
以上是一个基本介绍,具体细节望请查看mdn文档,proxy一般会用来配合reflect使用,下一节会介绍reflect。
ES6语法Proxy的基本使用