最近在复习Vue,不可避免的会接触到vue3,所以也不可避免的会思考这些问题

  1. vue3实现响应式为什么要使用proxy替换Object.defineProperty?Proxy对比Object.defineProperty有啥优缺点?
  2. 怎么通过Proxy实现响应式?

本文会回答这两个问题,通过这些问题探讨Proxy,以及Proxy在日常开发中的应用场景。

认识Proxy

Proxy意思翻译过来就是代理,外界对目标对象的访问都会被Proxy拦截,从而可以实现基本操作的拦截和自定义。

用法

let proxy = new Proxy(target,handler)

目前proxy支持13种行为的拦截

handler方法 何时触发
get 读取属性
set 写入属性
has in操作符
deleteProperty delete操作符
apply 函数调用
construct new操作符
getPrototypeOf Object.getPrototypeOf
setPrototypeOf Object.setPrototypeOf
isExtensible Object.isExtensible
preventExtensions Object.preventExtensions
defineProperty Object.defineProperty,<br />Object.defineProperties
getOwnPropertyDescriptor Object.getOwnPropertyDescriptor,<br />for...in,<br />Object.keys/values/entries
ownKeys Object.getOwnPropertyNames,<br />Object.getOwnPropertySymbols,<br />for...in,<br />Object.keys/values/entries

Reflect

reflect翻译过来是映射的意思,在MDN上是这样定义的

Reflect 是一个内置的对象,它提供拦截 JavaScript 操作的方法。

每个可用的代理捕捉器(trap)都有一个对应的同名Reflect函数,并能产生相同的行为。

let obj = {
    a: 10,
    name: 'oyc'
}

let newTarget = new Proxy(obj, {
    set(target, key, val) {
        console.log(`Set ${key}=${val} `);
    }
})

// newTarget.a = 20;  //Set a=20
// Reflect.set(newTarget, 'a', 20); //Set a=20

newTarget.name = 'oyq'; //Set name=oyq

Reflect.set(newTarget, 'name', 'oyq'); //Set name=oyq

从这可以看出,Reflect和trap表现出来的行为是相同的。所以当你为如何去触发trap而烦恼的时候,也许这个Reflect可以帮到你。

两个问题

大致学习完proxy的内容后,再来尝试解答下页头提到的两个个问题。