JavaScript进阶(十五):proxy 的基本使用 has、get、set、deleteProperty

首先,我们先稍微介绍下 proxy 的历史。

实际上来说,proxy 它的前身并不是 defineProperty,它的前身其实是另一个东西,叫做 observe。

observe 的作用和 proxy 差不多,也是可以监听某一个对象的一些修改之类的东西。

但是它已经被废弃掉了,如果你去查 MDN、W3C 手册之类的,它都会给你划一个红框,告诉你这个东西已经废弃掉了,建议你用 proxy 代替等等,所以现在极少数还在用或者是知道有 observe 这个东西。

 

那么接下来,我们的第一个问题莫过于 proxy 怎么用,其实它的基本使用是非常简单的。

首先,我们依然和前面一样,需要先准备一个真实的数据,这个数据是要藏在背后的,它并不会被人真的去修改

然后接下来注意了,和之前就有点不一样了,我们需要 new 一个 Proxy:

并且,第一个参数你需要告诉它,我要监听谁:

proxy 翻译成中文,就是代理的意思。你找他有事吗?找他有事你跟我说,你别直接找他,就这样一个意思。

然后第二个参数就是一个 json:

然后在这个 json 里面有各种各样的方法。

当然,原来的 defineProperty 其实有点太过于复杂了,所以说在这它有很多东西直接被取消掉了。

那么在 proxy 这里面,有几种方法可以用。

第一种:has。

has,是专门用于 in 操作的,你需要返回一个 true 或者 false。

和我们平常是一样的用法,比如:

 

第二种 get,第三种 set:

这两个就不用说了,get 获取操作,set 设置操作。

 

第四种:delete。

delete 是 js 的关键字,所以它不能直接叫 delete,而是叫做 deleteProperty,它是专门用来删除的。

 

这 4 种是最有用的,接下来,我们不妨来试试。

首先,new Proxy(),它会给我们返回一个对象 p 出来,当然叫什么名字都行:

接下来,我们就不能再去操作那个原始的数据对象 _data 了。

注意,这跟我们前面说的 defineProperty 有点不一样。

比如我们来试试:

in _data 就不会触发 has,而 in p 就会触发 has 操作,这个是和 defineProperty 不一样的地方。

注意,defineProperty 你就操作那个原始对象就行。

而 proxy,你需要操作那个新对象。

这是一个小小的区别,当然顺便一说,也就因为这个原因,所以 proxy 性能比 defineProperty 要高。

 

那么接下来,我们想要来实现这些操作,就得知道它的参数是什么。

对于 has 来说,有两个参数:

第一个是 data。这个 data,其实就等价于上面的 _data:

这时候大家可能很奇怪,我们直接用 _data 不就行了吗?为什么还要给我一个?

原因很简单,它为了预防一种情况,就是你直接写进去,压根就没给它取名字:

所以 has 的第一个参数是 data,就是你监听的那个数据对象。

然后第二个参数就是 name,它到底查询的是哪个属性:

那么接下来,我们就做个判断:

如果这个属性在我的 data 身上,那么我就 return true,如果不在就 return false。

 

然后 get 也有两个参数:

data,你监听的那个数据对象。(其实它每次都会把这个 data 给你,所以我们上面压根就不用存)

name,它到底获取的是哪个属性。

所以,我们这也来做个判断:

如果这个 name 在 data 身上,那就直接返回出去。如果不在,就说明没这个数据,你试图找我要一个不存在的东西,那我就给你报错。

 

以及接下来 set,它有 3 个参数,相信不用往下看,就已经猜到都有谁了。

所以你会发现它们几个都没有什么本质的区别。

 

在接下来,还有个 deleteProperty,它也一样,有两个参数。

data,从哪删。

name,删谁。

 

现在我们就已经认识了 proxy,那接下来,是时候对它做些事情了,如果说和 defineProperty 没啥区别,那我们为啥要用它?

首先,我们增加一个 arr,然后在 set 里面 console 一句话:

你可以看到,我们对 a 进行设置,是有 set 的。

而对 arr 设置,却没有打印 set,说明它是没走 set 的。为什么会这样?

原因非常的简单,并不是我们用了 proxy 就一切都解决了。

实际上来说,现在跟刚才是没变化的,你的这个 proxy 监听的是谁?

你这个 proxy 监听的是你让它监听的那个东西,也就是 _data:

别说 arr,比如我们换一个 json:

你可以看到,也一样没反应。

所以,并不是说 proxy 能够自动的帮我们解决这一系列的问题,只是说它比 defineProperty 更方便而已。

我们先认清这个事,它在这一点上来说,不处理的情况下,proxy 和 defineProperty 没什么区别。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章